内核中各种出错函数处理总结.doc

  1. 1、本文档共10页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
1、许多的内核函数需要返回一个指针,但是函数的调用可能失败,一般我们处理这样的情形都是返回一个NULL指针,就像malloc或kmalloc在没有获得指定的空间申请时的返回值一样。但是有时我们想知道导致函数失败的原因,但是返回NULL就显得信息不够。因此有些函数返回一个实际的错误编码以便对引起错误的原因做一些处理。很多内核接口通过把错误值编码到一个指针值中来返回错误信息。当处理这样的函数时,判断是否成功调用就不能是简单的和NULL进行比较。为了方便使用这样的类型接口,2.6的内核在linux/err.h中实现了三个内联函数: #define MAX_ERRNO 4095 #ifndef __ASSEMBLY__ #define IS_ERR_VALUE(x) unlikely((x) = (unsigned long)-MAX_ERRNO) 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); } 所幸的是,内核返回的指针一般是指向页面的边界(4K边界),即 ptr 0xfff == 0 这样ptr的值不可能落在(0xfffff000,0xffffffff)之间, 而一般内核的出错代码也是一个小负数,在-1000到0之间,转变成unsigned long, 正好在(0xfffff000,0xffffffff)之间。因此可以用 (unsigned long)ptr (unsigned long)-1000L 来判断内核函数的返回值是一个有效的指针,还是一个出错代码。像struct class *cls = class_create();这种语句,其中返回的指针值并不是kmalloc一样这么简单,只判断是否为NULL就可以了,内核是返回其错误值。那么我怎么来判断它呢,总不能用if()来将每个错误例出来吧,这里我们的IS_ERR()宏就发挥作用了。先看源代码,再讲原理,看看内核中的巧妙设计思路。 /* include/linux/err.h */ static inline long __must_check IS_ERR(const void *ptr) { return IS_ERR_VALUE((unsigned long)ptr); } #define IS_ERR_VALUE(x) unlikely((x) = (unsigned long)-MAX_ERRNO) 内核中的函数常常返回指针,问题是如果出错,也希望能够通过返回的指针体现出来。 所幸的是,内核返回的指针一般是指向页面的边界(4K边界),即 ptr 0xfff == 0 这样ptr的值不可能落在(0xfffff000,0xffffffff)之间,而一般内核的出错代码也是一个小负数,在-1000到0之间,转变成unsigned long,正好在(0xfffff000,0xffffffff)之间。因此可以用 (unsigned long)ptr (unsigned long)-1000L 也就等效于(x) = (unsigned long)-MAX_ERRNO 其中MAX_ERRNO 为4095 来判断内核函数的返回值是一个有效的指针,还是一个出错代码。 涉及到的任何一个指针,必然有三种情况,一种是有效指针,一种是NULL,空指针,一种是错误指针,或者说无效指针.而所谓的错误指针就是指其已经到达了 最后一个page.比如对于32bit的系统来说,内核空间最高地址0xffffffff,那么最后一个page就是指的 0xfffff000~0xffffffff(假设4k一个page).这段地址是被保留的,如果超过这个地址,则肯定是错误的。 而我们的错误码的值在内存中定义都是这样的(include/linux/errno.h): #define ENOLCK 77 /* No record locks available */ #define ENOSYS 78 /* Function not implemented */ #define ENOMSG 80 /* No message of desired type */ #define EIDRM 81 /* Identifier removed */ #define ENOSR 82 /* Out of streams

文档评论(0)

jgx3536 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

版权声明书
用户编号:6111134150000003

1亿VIP精品文档

相关文档