当前位置: 首页 > news >正文

Linux内核err.h文件分析

在阅读和编写内核相关的代码时,经常会看到IS_ERR、ERR_PTR等函数。这些函数在内核头文件的err.h中。以我服务器的代码为例,内核版本为5.15。
在这里插入图片描述
这个文件的代码如下:

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_ERR_H
#define _LINUX_ERR_H#include <linux/compiler.h>
#include <linux/types.h>#include <asm/errno.h>/** Kernel pointers have redundant information, so we can use a* scheme where we can return either an error code or a normal* pointer with the same return value.** This should be a per-architecture thing, to allow different* error and pointer decisions.*/
#define MAX_ERRNO	4095#ifndef __ASSEMBLY__#define IS_ERR_VALUE(x) unlikely((unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO)static inline void * __must_check ERR_PTR(long error)
{return (void *) error;
}static inline long __must_check PTR_ERR(__force const void *ptr)
{return (long) ptr;
}static inline bool __must_check IS_ERR(__force const void *ptr)
{return IS_ERR_VALUE((unsigned long)ptr);
}static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr)
{return unlikely(!ptr) || IS_ERR_VALUE((unsigned long)ptr);
}/*** ERR_CAST - Explicitly cast an error-valued pointer to another pointer type* @ptr: The pointer to cast.** Explicitly cast an error-valued pointer to another pointer type in such a* way as to make it clear that's what's going on.*/
static inline void * __must_check ERR_CAST(__force const void *ptr)
{/* cast away the const */return (void *) ptr;
}static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr)
{if (IS_ERR(ptr))return PTR_ERR(ptr);elsereturn 0;
}#endif#endif /* _LINUX_ERR_H */

这个文件提供了一套用于处理错误指针的宏和函数。主要部分的解释:

#define MAX_ERRNO 4095:定义了最大的错误号为4095。

#define IS_ERR_VALUE(x) unlikely((unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO):定义了一个宏,用于检查一个值是否在错误号的范围内。

ERR_PTR(long error):这个函数将一个错误号转换为一个错误指针,这样就可以将错误信息通过指针返回。

PTR_ERR(const void *ptr):这个函数将一个错误指针转换回对应的错误号。

IS_ERR(const void *ptr):这个函数检查一个指针是否是错误指针。

IS_ERR_OR_NULL(const void *ptr):这个函数检查一个指针是否是错误指针或者NULL指针。

ERR_CAST(const void *ptr):这个函数将一个错误指针强制转换为另一种类型的指针。

PTR_ERR_OR_ZERO(const void *ptr):这个函数检查一个指针,如果它是错误指针,就返回对应的错误号,否则返回0。

这些函数和宏提供了一种机制,使得函数可以通过返回指针的方式来返回错误信息。

错误号的部分信息在文件errno.h中
代码如下:

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_ERRNO_H
#define _LINUX_ERRNO_H#include <uapi/linux/errno.h>/** These should never be seen by user programs.  To return one of ERESTART** codes, signal_pending() MUST be set.  Note that ptrace can observe these* at syscall exit tracing, but they will never be left for the debugged user* process to see.*/
#define ERESTARTSYS	512
#define ERESTARTNOINTR	513
#define ERESTARTNOHAND	514	/* restart if no handler.. */
#define ENOIOCTLCMD	515	/* No ioctl command */
#define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
#define EPROBE_DEFER	517	/* Driver requests probe retry */
#define EOPENSTALE	518	/* open found a stale dentry */
#define ENOPARAM	519	/* Parameter not supported *//* Defined for the NFSv3 protocol */
#define EBADHANDLE	521	/* Illegal NFS file handle */
#define ENOTSYNC	522	/* Update synchronization mismatch */
#define EBADCOOKIE	523	/* Cookie is stale */
#define ENOTSUPP	524	/* Operation is not supported */
#define ETOOSMALL	525	/* Buffer or request is too small */
#define ESERVERFAULT	526	/* An untranslatable error occurred */
#define EBADTYPE	527	/* Type not supported by server */
#define EJUKEBOX	528	/* Request initiated, but will not complete before timeout */
#define EIOCBQUEUED	529	/* iocb queued, will get completion event */
#define ERECALLCONFLICT	530	/* conflict with recalled state */
#define ENOGRACE	531	/* NFS file lock reclaim refused */#endif

错误号的部分解释如下

ERESTARTSYS (512):系统调用由于接收到一个可以被处理的信号而被中断,需要被重新启动。

ERESTARTNOINTR (513):系统调用由于某些原因被中断,需要被重新启动,但是不需要检查未决的信号。

ERESTARTNOHAND (514):系统调用由于接收到一个不能被当前进程处理的信号而被中断,需要被重新启动。

ENOIOCTLCMD (515):没有找到对应的ioctl命令。

ERESTART_RESTARTBLOCK (516):系统调用需要被重新启动,但是使用了不同的方法。

EPROBE_DEFER (517):设备驱动程序请求延迟探测。

EOPENSTALE (518):打开操作找到了一个过时的目录项。

ENOPARAM (519):不支持的参数。

EBADHANDLE (521):NFS协议中的非法文件句柄。

ENOTSYNC (522):更新同步不匹配。

EBADCOOKIE (523):Cookie过期。

ENOTSUPP (524):不支持的操作。

ETOOSMALL (525):缓冲区或请求太小。

ESERVERFAULT (526):发生了无法翻译的错误。

EBADTYPE (527):服务器不支持的类型。

EJUKEBOX (528):请求已经启动,但在超时前不会完成。

EIOCBQUEUED (529):iocb已经入队,将会收到完成事件。

ERECALLCONFLICT (530):与被召回的状态冲突。

ENOGRACE (531):NFS文件锁恢复被拒绝。

相关文章:

  • springboot基本使用八(mbatisplus+filter实现登录功能)
  • ADC重要的信噪比公式是怎么来的?
  • Python自动连接SSH
  • Redis入门三(主从复制、Redis哨兵、Redis集群、缓存更新策略、缓存穿透、缓存击穿、缓存雪崩)
  • 算法学习——LeetCode力扣动态规划篇8
  • MATLAB 自定义生成直线点云(详细介绍) (47)
  • JSQLParserException异常
  • OpenHarmony无人机MAVSDK开源库适配方案分享
  • Mac 装 虚拟机 vmware、centos7等
  • phpspreadsheet导出Excel报错问题汇总
  • 运筹学基础(二):求解整数规划的分支定界法(branch and bound)
  • 快速上手Spring Cloud 九:服务间通信与消息队列
  • Docker Stack(堆栈) 部署多服务集群,多服务编排
  • python电商结合双轨制
  • 推特Twitter有直播功能吗?如何用Twitter直播?
  • JavaScript 如何正确处理 Unicode 编码问题!
  • [case10]使用RSQL实现端到端的动态查询
  • 【知识碎片】第三方登录弹窗效果
  • canvas绘制圆角头像
  • flutter的key在widget list的作用以及必要性
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • JavaScript中的对象个人分享
  • jQuery(一)
  • Laravel Telescope:优雅的应用调试工具
  • Phpstorm怎样批量删除空行?
  • Python利用正则抓取网页内容保存到本地
  • Spring声明式事务管理之一:五大属性分析
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 机器学习学习笔记一
  • 聚类分析——Kmeans
  • 巧用 TypeScript (一)
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 实习面试笔记
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 移动端解决方案学习记录
  • 做一名精致的JavaScripter 01:JavaScript简介
  • 7行Python代码的人脸识别
  • 数据可视化之下发图实践
  • ###项目技术发展史
  • #define 用法
  • #微信小程序(布局、渲染层基础知识)
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (C++20) consteval立即函数
  • (NSDate) 时间 (time )比较
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (一)Java算法:二分查找
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • (转)平衡树