file_operations数据结构分析

一、引言

        struct file代表一个打开的文件,在执行file_operation中的open操作时被创建,这里需要注意的是与用户空间inode指针的区别,一个在内核,而file指针在用户空间,由c库来定义。

        file结构体是文件系统的主要数据结构,每个file实例都包含一个指向file_operations结构体的指针,该结构保存了指向所有可能文件系统的函数指针。

二、数据结构描述

       数据结构struct file_operation数据描述如下:

struct file_operations {
	struct module *owner;
	loff_t (*llseek) (struct file *, loff_t, int);
	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
	ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
	ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
	int (*readdir) (struct file *, void *, filldir_t);
	unsigned int (*poll) (struct file *, struct poll_table_struct *);
	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
	int (*mmap) (struct file *, struct vm_area_struct *);
	int (*open) (struct inode *, struct file *);
	int (*flush) (struct file *, fl_owner_t id);
	int (*release) (struct inode *, struct file *);
	int (*fsync) (struct file *, loff_t, loff_t, int datasync);
	int (*aio_fsync) (struct kiocb *, int datasync);
	int (*fasync) (int, struct file *, int);
	int (*lock) (struct file *, int, struct file_lock *);
	ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
	int (*check_flags)(int);
	int (*flock) (struct file *, int, struct file_lock *);
	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
	ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
	int (*setlease)(struct file *, long, struct file_lock **);
	long (*fallocate)(struct file *file, int mode, loff_t offset,
			  loff_t len);
};
        现在一个一个分析其含义:

三、域成员分析

1. owner

变量:

         struct module *owner;

功能:

        module:一般初始化为THIS_MODULE,定义在<linux/module.h>中的宏。

2.llseek

变量:

        loff_t (*llseek) (struct file *, loff_t, int);

参数:

        指针file为进行读取信息的目标文件结构体指针;

        参数loff_t为文件定位的目标偏移量;

        参数int为对文件定位的起始地址,这个值可以为文件开头(SEEK_SET,0);当前位置(SEEK_CUR,1),文件末尾(SEEK_END,2);

功能:

        用作改变文件中的当前读/写位置, 并且新位置作为(正的)返回值。

        如果这个函数指针是NULL, seek 调用会以潜在地无法预知的方式修改 file 结构中的位置计数器( 在"file 结构" 一节中描述).

注:loff_t 参数是一个"long offset", 并且就算在 32位平台上也至少 64 位宽. 错误由一个负返回值指示.

3. read

变量:

        ssize_t(*read) (struct file *, char __user *, size_t, loff_t *);

参数:

        指针参数 file为进行读取信息的目标文件;

        指针参数char为对应放置信息的缓冲区(即用户空间内存地址),

        参数size_t为要读取的信息长度,

        参数loff_t 为读的位置相对于文件开头的偏移,在读取信息后,这个指针一般都会移动,移动的值为要读取信息的长度值

功能:

        从设备中获取数据. 在这个位置的一个空指针导致 read 系统调用以 -EINVAL("Invalidargument") 失败. 一个非负返回值代表了成功读取的字节数,返回值是一个 "signed size" 类型。

注1:"signed size"常常是目标平台本地的整数类型

注2:write为阻塞操作。

4. write

变量:

        ssize_t(*write) (struct file *, const char __user *, size_t, loff_t *)

参数:

        参数filp为目标文件结构体指针,

        buffer为要写入文件的信息缓冲区,

        count为要写入信息的长度,

        ppos为当前的偏移位置,这个值通常是用来判断写文件是否越界

功能:

        发送数据给设备. 如果NULL, -EINVAL 返回给调用 write 系统调用的程序. 如果非负, 返回值代表成功写的字节数.

注:write为阻塞操作。

5. aio_read

变量:

        ssize_t(*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

参数:

        与read函数相比,第一、二、三个参数是不同的,异步读写的第三个参数直接传递值,而同步读写的第三个参数传递的是指针,因为AIO从来不需要改变文件的位置。异步读写的第一个参数为指向kiocb结构体的指针,而同步读写的第一参数为指向file结构体的指针,每一个I/O请求都对应一个kiocb结构体;

功能:

        初始化一个异步读 -- 可能在函数返回前不结束的读操作.如果这个方法是 NULL, 所有的操作会由 read 代替进行(同步地).

6. aio_write

变量:

        size_t(*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

参数:

        同aio_read;

功能:

        初始化设备上的一个异步写。

7. readdir

变量:

        int(*readdir) (struct file *, void *, filldir_t);

参数:

        file文件对象指针

        filldir_t是一个"filldir"函数类型, used by readdir()

功能:

        它用来读取目录, 并且仅对文件系统有用,只对目录对象适用。

8. poll

变量:

        unsigned int (*poll) (struct file*, struct poll_table_struct *);

参数:

        file表示文件对象结构指针;

        poll_table_struct表示轮询表指针。

功能:

        轮询函数

        函数返回设备资源的可获取状态,即POLLIN,POLLOUT,POLLPRI,POLLERR,POLLNVAL等宏的位“或”结果。

        每个宏都表明设备的一种状态,如:POLLIN(定义为0x0001)意味着设备可以无阻塞的读,POLLOUT(定义为0x0004)意味着设备可以无阻塞的写。

9. unlocked_ioctl

变量:

        long(*unlocked_ioctl) (struct file *, unsigned int, unsigned long);

功能:

        因为ioctl是在Big Kernel Lock (BKL)下运行,但是现在内核已经删除了BKl,因此修改了此函数。

        ioct系统调用提供了发出设备特定命令的方法

注:参考http://lwn.net/Articles/119652/

10. compat_ioctl

变量:

        long(*compat_ioctl) (struct file *, unsigned int, unsigned long);

功能:

        implementioctl processing for 32 bit process on 64 bit system(用来提供32位用户态程序的方法)

注:参考http://lwn.net/Articles/119652/

11. mmap

变量:

        int(*mmap) (struct file *, struct vm_area_struct *);

参数:

        file表示文件对象指针;

        vm_area_struct表示进程地址空间

功能:

        mmap 用来请求将设备内存映射到进程的地址空间. 如果这个方法是 NULL, mmap 系统调用返回 -ENODEV.

12. open

变量:

        int(*open) (struct inode *, struct file *);

参数:

        inode 为文件索引节点,文件索引节点只有一个,无论用户打开多少个文件,都只是对应着一个inode结构;

        filp为文件对象结构体,只要打开一个文件,就对应着一个file结构体,file结构体通常用来追踪文件在运行时的状态信息)

功能:

        打开文件操作

        与release函数对应;

13. flush

变量:

        int(*flush) (struct file *, fl_owner_t id);

参数:

        指针file,表示操作的文件对象

        fl_owner_t的定义typedefstruct files_struct *fl_owner_t;

功能:

           flush 操作在进程关闭它的设备文件描述符的拷贝时调用; 它应当执行(并且等待)设备的任何未完成的操作.
注:这个必须不要和用户查询请求的 fsync 操作混淆了. 当前, flush 在很少驱动中使用;SCSI 磁带驱动使用它, 例如, 为确保所有写的数据在设备关闭前写到磁带上. 如果 flush 为 NULL, 内核简单地忽略用户应用程序的请求.

14. release

变量:

        int(*release) (struct inode *, struct file *);

参数:

        同open;

功能:

        清理未结束的输入输出操作,释放资源,用户自定义排他标志的复位等。

        release ()函数当最后一个打开设备的用户进程执行close()系统调用的时候,内核将调用驱动程序release()函数:

15.  fsync

变量:

        int(*fsync) (struct file *, loff_t, loff_t, int datasync);

功能:

        刷新待处理的数据,允许进程把所有的脏缓冲区刷新到磁盘。

16. aio_fsync

变量:

        int(*aio_fsync) (struct kiocb *, int datasync);

功能:

        把文件所指定的文件的所有脏缓冲区写到磁盘中(异步刷新)

17. fasync

变量:

        int(*fasync) (int, struct file *, int);

功能:

        该函数是系统支持异步通知的设备驱动;

18. lock

变量:

        int(*lock) (struct file *, int, struct file_lock *);

功能:

        该方法实现文件加锁。

19. readv与writev

变量:

       ssize_t (*readv) (struct file *, const struct iovec *, unsigned long,loff_t *);

       ssize_t (*writev) (struct file *, const struct iovec *, unsigned long,loff_t *);

功能:

        用于同名系统调用的实现,用以实现向量的读取和写入,(向量本质上是一个结构,用以提供一个非连续的内存区域,防止读入的信息和写入的数据,该技术称为快速发散-聚集)

        可以便面多次的read/write,以免降低性能。

20. sendpage

变量:

        ssize_t(*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);

功能:

        sendpage 是 sendfile 的另一半; 它由内核调用来发送数据, 一次一页,到对应的文件. 设备驱动实际上不实现 sendpage.

21. get_unmapped_area

变量:

        unsignedlong (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsignedlong, unsigned long);

功能:

        在进程的地址空间找一个合适的位置来映射在底层设备上的内存段中.

22. check_flags

变量:

        int(*check_flags)(int);

功能:

        检查传递给 fnctl(F_SETFL...) 调用的标志.

23. flock

变量:

        int(*flock) (struct file *, int, struct file_lock *);

功能:

    实现文件锁;

24. splice_write与splice_read

变量:

        ssize_t(*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t,unsigned int);

        ssize_t(*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t,unsigned int);

功能:

        用于从管道想文件传输数据,繁殖依然,目前只用于splice2系统调用;

25. setlease

变量:

        int(*setlease)(struct file *, long, struct file_lock **);

功能:

        sets alease on an open file;

26. fallocate

变量:

        long(*fallocate)(struct file *file, int mode, loff_t offset, loff_t len);

功能:

        通过设置mode标志FA_ALLOCATE或FA_DEALLOCATE,表示preallocation and deallocation of preallocated blocks respectively,由sys_fallocate调用。

四、参考资料

   http://www.cnblogs.com/ZJoy/archive/2011/01/09/1931379.html


原文地址:https://www.cnblogs.com/youngerchina/p/5624633.html