问题:大家在使用open函数或则read、write函数时有没有考虑过,文件描述符到底有什么用?他是怎么让内核的read、write函数执行起来的?
大家先看下这个结构体:
struct file
{
//...
mode_t f_mode;
loff_t f_pos;
unsigned int f_flags;
struct file_operations *f_op;
void *private_data;
struct dentry *f_dentry;
int refcnt;
//...
};
这个结构体对象也被称为文件引擎,因为里面包含了对于文件操作的很多信息。这个结构体中的 *f_op成员指向的是函数操作集(这里不必深究这个函数操作集从哪里来,因为涉及到内核很多的东西)。
什么叫做函数操作集?
函数操作集就是将open函数、write、read等函数封装进了一个结构体中。日后*f_op指向了这个结构体对象的地址,就可以通过f_*op来使用这些函数。
这里再给大家介绍一些文件描述符数组。
文件描述符数组里存放的就是flie对象的地址,每个进程对应着一个文件描述符数组。
那文件描述符到底怎么被内核使用呢,这里对系统调用函数所用到的文件描述符进行解释。
大家都知道呢,文件描述符就是 int fd 这样在应用程序定义的,当它作为write的参数时,它就会被内核当做成描述符数组的下标,从而找到对应的file对象。这里前面已经说过file对象也就是文件引擎,内核会再通过*f_op这个成员找到函数操作集里的对应驱动程序进行执行(如果是设备文件的话,否则就在系统调用函数里面执行相关操作)。