IS_ERR()、PTR_ERR() and ERR_PTR() in Linux Kernel
カーネル内の関数はポインタを返すことが多く、通常呼び出しエラーが発生するとNULL空のポインタが返されますが、linuxはより優れた処理を行い、返されたポインタで表現することができます.
いずれのポインタに対しても、有効なポインタ、NULL、空のポインタ、エラーポインタ、または無効なポインタの3つのケースがあります.エラーポインタとは、32 bitのシステムにとってカーネル空間最高アドレス0 xffffffffが最後のpageに達したことを意味し、最後のpageは0 xfffff 000~0 xffffff(4 Kサイズページを例に)を意味する.このアドレスは保持されていますが、このアドレスを超えると間違いに違いありません.
include/linux/err.hにはこのメカニズムの処理が含まれており,主にIS_を介している.ERR, PTR_ERR, ERR_PTRのいくつかのマクロ.
したがって、カーネルに返されるポインタについて、エラーをチェックする方法はif(!retptr)ではなくif(IS_ERR(retptr)または
If( IS_ERR_VALUE(retptr) ).
カーネル内の関数はしばしばポインタを返しますが、問題はエラーが発生した場合でも、返されたポインタで表現したいということです.全体的に、カーネルがポインタを返すと、合法的なポインタ、NULLポインタ、不正なポインタの3つのケースがあります.
1)合法的なポインタ:カーネルが返すポインタは一般的にページの境界(4 K境界)、すなわちptr&0 xfff==0を指す
2)不正ポインタ:ptrの値は(0 xfffff 000,0 xffffffff)の間に落ちることは不可能であり(この区間はカーネルのハイエンドメモリが存在する区間である)、一般的なカーネルのエラーコードも小さな負数であり、-1000から0の間にunsigned longに変換され、ちょうど(0 xfffff 000,0 xffffffff)の間にある.だから使える
(unsigned long)ptr > (unsigned long)-1000L
-1000 L=0 xfffff 000 3)不正なポインタを使用して、エラーの分類を行います.
カーネル関数の戻り値が有効なポインタなのか、エラーコードなのかを判断します.
MAX_ERRNOは?4095、MAX_と定義されたマクロERRNOは最大のエラー番号であり、Linuxカーネルでは、エラーが多くの可能性がある.
Linuxカーネルのエラーについてはinclude/asm-generic/errno-baseを見てみましょう.hファイル:
最もよく見られるのは-EBUSY,-EINVAL,-ENODEV,-EPIPE,-EAGAIN,-ENOMEMです.Linuxを使ったことがある限り、これらの間違いを見たことがあります.それは確かによくあるからです.これらは各アーキテクチャにあるものであり、また各アーキテクチャも独自のエラーコードを定義している.これらのものはもちろんマクロで、実際にはいくつかの数字に対応しています.この数字はエラー番号と呼ばれています.Linuxカーネルにとって、どのアーキテクチャにおいても、最も多く、エラー番号は4095を超えない.4095はちょうど4 kより1小さい、すなわち4096が1.一つのpageは4 kかもしれないし、もっと多いかもしれないことを知っています.例えば8 kですが、少なくともそれは4 kなので、pageを残しておくと、カーネル空間のポインタを記録することができます.どういう意味ですか.例えばここのIS_ERR()は、kthread_を判断するrun()が返すポインタが間違っているかどうか、ポインタが最後のpageを指していない場合は問題なく、申請に成功し、ポインタが最後のpageを指している場合は、実際には有効なポインタではないことを示し、このポインタに保存されているのは実際にはエラーコードである.一般的によく使われる方法はISを先に使うことですERR()は、エラーであるか否かを判断し、そうであればPTR_を呼び出すERR()はこのエラーコードを返す.ただPTRは呼び出されていませんERR()ですが、決定的な役割を果たしているのはISですから.ERR()、PTR_ERR()はエラーコードを返すだけです.つまり、呼び出し者に情報を提供します.エラーが発生しているかどうかを知るだけで、何のためにエラーが発生しているのか気にしないでください.PTRを呼び出す必要はありません.ERR()です
いずれのポインタに対しても、有効なポインタ、NULL、空のポインタ、エラーポインタ、または無効なポインタの3つのケースがあります.エラーポインタとは、32 bitのシステムにとってカーネル空間最高アドレス0 xffffffffが最後のpageに達したことを意味し、最後のpageは0 xfffff 000~0 xffffff(4 Kサイズページを例に)を意味する.このアドレスは保持されていますが、このアドレスを超えると間違いに違いありません.
include/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) ).
カーネル内の関数はしばしばポインタを返しますが、問題はエラーが発生した場合でも、返されたポインタで表現したいということです.全体的に、カーネルがポインタを返すと、合法的なポインタ、NULLポインタ、不正なポインタの3つのケースがあります.
1)合法的なポインタ:カーネルが返すポインタは一般的にページの境界(4 K境界)、すなわちptr&0 xfff==0を指す
2)不正ポインタ:ptrの値は(0 xfffff 000,0 xffffffff)の間に落ちることは不可能であり(この区間はカーネルのハイエンドメモリが存在する区間である)、一般的なカーネルのエラーコードも小さな負数であり、-1000から0の間にunsigned longに変換され、ちょうど(0 xfffff 000,0 xffffffff)の間にある.だから使える
(unsigned long)ptr > (unsigned long)-1000L
-1000 L=0 xfffff 000 3)不正なポインタを使用して、エラーの分類を行います.
カーネル関数の戻り値が有効なポインタなのか、エラーコードなのかを判断します.
MAX_ERRNOは?4095、MAX_と定義されたマクロERRNOは最大のエラー番号であり、Linuxカーネルでは、エラーが多くの可能性がある.
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です.Linuxを使ったことがある限り、これらの間違いを見たことがあります.それは確かによくあるからです.これらは各アーキテクチャにあるものであり、また各アーキテクチャも独自のエラーコードを定義している.これらのものはもちろんマクロで、実際にはいくつかの数字に対応しています.この数字はエラー番号と呼ばれています.Linuxカーネルにとって、どのアーキテクチャにおいても、最も多く、エラー番号は4095を超えない.4095はちょうど4 kより1小さい、すなわち4096が1.一つのpageは4 kかもしれないし、もっと多いかもしれないことを知っています.例えば8 kですが、少なくともそれは4 kなので、pageを残しておくと、カーネル空間のポインタを記録することができます.どういう意味ですか.例えばここのIS_ERR()は、kthread_を判断するrun()が返すポインタが間違っているかどうか、ポインタが最後のpageを指していない場合は問題なく、申請に成功し、ポインタが最後のpageを指している場合は、実際には有効なポインタではないことを示し、このポインタに保存されているのは実際にはエラーコードである.一般的によく使われる方法はISを先に使うことですERR()は、エラーであるか否かを判断し、そうであればPTR_を呼び出すERR()はこのエラーコードを返す.ただPTRは呼び出されていませんERR()ですが、決定的な役割を果たしているのはISですから.ERR()、PTR_ERR()はエラーコードを返すだけです.つまり、呼び出し者に情報を提供します.エラーが発生しているかどうかを知るだけで、何のためにエラーが発生しているのか気にしないでください.PTRを呼び出す必要はありません.ERR()です