您的位置:首页 > 运维架构 > Linux

Linux中IS_ERR()函数的理解

2013-12-25 22:06 246 查看

在Linux源码中的fs部分,经常会碰到这样的函数(位于kernel/include/linux/fs.h):

/*

* Kernel>

static>
retval = PTR_ERR(dir_page);

>IS_ERR()有一些妙处。

内核中的函数常常返回指针,问题是如果出错,也希望能够通过返回的指针体现出来。

所幸的是,内核返回的指针一般是指向页面的边界(4K边界),即

ptr & 0xfff == 0

这样ptr的值不可能落在(0xfffff000,0xffffffff)之间,

而一般内核的出错代码也是一个小负数,在-1000到0之间,转变成unsigned long,

正好在(0xfffff000,0xffffffff)之间。因此可以用

(unsigned long)ptr > (unsigned long)-1000L

来判断内核函数的返回值是一个有效的指针,还是一个出错代码。

涉及到的任何一个指针,必然有三种情况,一种是有效指针,一种是NULL,空指针,一种是错误指针,或者说无效指针.而所谓的错误指针就是指其已经到达了最后一个page.比如对于32bit的系统来说,内核空间最高地址0xffffffff,那么最后一个page就是指的0xfffff000~0xffffffff(假设4k一个page).这段地址是被保留的,如果超过这个地址,则肯定是错误的。

Linux内核中,出错有多种可能:

include/asm-generic/errno-base.h文件:

#define EPERM 1 /* Operation not permitted */

#define ENOENT 2 /* No such file or directory */

#define ESRCH 3 /* No such process */

#define EINTR 4 /* Interrupted system call */

#define EIO 5 /* I/O error */

#define ENXIO 6 /* No such device or address */

#define E2BIG 7 /* Argument list too long */

#define ENOEXEC 8 /* Exec format error */

#define EBADF 9 /* Bad file number */

#define ECHILD 10 /* No child processes */

#define EAGAIN 11 /* Try again */

#define ENOMEM 12 /* Out of memory */

#define EACCES 13 /* Permission denied */

#define EFAULT 14 /* Bad address */

#define ENOTBLK 15 /* Block device required */

#define EBUSY 16 /* Device or resource busy */

#define EEXIST 17 /* File exists */

#define EXDEV 18 /* Cross-device link */

#define ENODEV 19 /* No such device */

#define ENOTDIR 20 /* Not a directory */

#define EISDIR 21 /* Is a directory */

#define EINVAL 22 /* Invalid argument */

#define ENFILE 23 /* File table overflow */

#define EMFILE 24 /* Too many open files */

#define ENOTTY 25 /* Not a typewriter */

#define ETXTBSY 26 /* Text file busy */

#define EFBIG 27 /* File too large */

#define ENOSPC 28 /* No space left on device */

#define ESPIPE 29 /* Illegal seek */

#define EROFS 30 /* Read-only file system */

#define EMLINK 31 /* Too many links */

#define EPIPE 32 /* Broken pipe */

#define EDOM 33 /* Math argument out of domain of func */

#define ERANGE 34 /* Math result not representable */

而出错时,往往返回的是-EBUSY,-EINVAL,-ENODEV,-EPIPE,-EAGAIN,-ENOMEM等等,可以看到,这个值实际上是在-1000~0之间的。

对于一个返回指针的函数,我们通常返回NULL表示失败,但是这不能指出那种失败(内存不足?硬件错误还是网络不可达?)

所以返回的时候用ERR_PTR(-ENOME) 等就可以判断,因为这个指针显然不合法

参考 include/iinux/err.h
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: