Chinaunix首页 | 论坛 | 博客
  • 博客访问: 269904
  • 博文数量: 22
  • 博客积分: 2490
  • 博客等级: 大尉
  • 技术积分: 752
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-31 15:35
文章分类

全部博文(22)

文章存档

2011年(5)

2010年(43)

2009年(14)

我的朋友

分类: LINUX

2010-05-11 14:20:24

内核IS_ERR宏解析
 
 
 
最近在使用filp_open打开文件时遇到到一个问题,当打开一个并不存在的文件时,filp_open返回值值为0xfffffffe,而并不是0(NULL),这是因为内核对返回指针的函数做了特殊处理。内核中的函数常常返回指针,通常如果调用出错,会返回NULL空指针,但linux做了更精妙的处理,能够通过返回的指针体现出来。
 
对任何一个指针,必然有三种情况:一种是有效指针,一种是NULL,空指针,一种是错误指针,或者说无效指针。而所谓的错误指针就是指其已经到达了最后一个page,比如对于32bit的系统来说,内核空间最高地址0xffffffff,那么最后一个page就是指的0xfffff000~0xffffffff(以4K大小页为例)。这段地址是被保留的,如果超过这个地址,则肯定是错误的。
 
在linux/err.h中包含了这一机制的处理,主要通过IS_ERR, PTR_ERR, ERR_PTR几个宏。
/*
 * Kernel pointers have redundant information, so we can use a
 * scheme where we can return either an error code or a dentry
 * pointer with the same return value.
 *
 * This should be a per-architecture thing, to allow different
 * error and pointer decisions.
 */
#define MAX_ERRNO       4095
 
#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
 
/* 将错误号转化为指针,由于错误号在-1000~0间,返回的指针会落在最后一页  */
static inline void *ERR_PTR(long error)
{
         return (void *) error;
}
 
/* 将指针转化为错误号  */
static inline long PTR_ERR(const void *ptr)
{
         return (long) ptr;
}
 
/* 判断返回的指针是错误信息还是实际地址,即指针是否落在最后一页 */
static inline long IS_ERR(const void *ptr)
{
         return IS_ERR_VALUE((unsigned long)ptr);
}
 
所以对于内核中返回的指针,检查错误的方式不是if(!retptr),而是if( IS_ERR(retptr) 或
If( IS_ERR_VALUE(retptr) )。
 
 
阅读(1570) | 评论(0) | 转发(0) |
0

上一篇:/etc/fstab详解

下一篇:0欧电阻的作用

给主人留下些什么吧!~~