file_operations 结构体

来源:互联网 发布:php快速排序算法 编辑:程序博客网 时间:2024/06/05 17:57

file_operations 结构体中的成员函数是字符设备驱动程序设计的主体内容,这些函数实际会在应用程序进行 Linux 的 open()、write()、read()、close() 等系统调用时最终被调用。file_operations 结构体目前已经比较庞大,它的定义如下:

 定义在 linux/include/linux/fs.h

 

struct file_operations {

 struct module *owner;

//拥有该结构的模块的指针,一般为 THIS_MODULES

 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);
// 仅用于读取目录,对于设备文件,该字段为NULL

 unsigned int (*poll) (struct file *, struct poll_table_struct *);
// 轮询函数,判断目前是否可以进行非阻塞的读取或写入  

int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

// 执行设备 I/O 控制命令

 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
//不使用BLK 文件系统,将使用此种函数指针代替 ioctl 

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

// 在64 系统上,32位的 ioctl调用将使用此函数指针代替
 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 *, struct dentry *, int datasync);

//这个方法是 fsync 系统调用的后端, 用户调用来刷新任何挂着的数据. 如果这个指针是 NULL, 系统调用返回 -EINVAL 

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

//异步 fsync
 int (*fasync) (int, struct file *, int);

//通知设备 FASYNC 标志发生变化
 int (*lock) (struct file *, int, struct file_lock *);

//lock 方法用来实现文件加锁; 加锁对常规文件是必不可少的特性, 但是设备驱动几乎从不实现它.
 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);

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

// 在进程地址空间找到一个将底层设备中的内存段映射的位置
 int (*check_flags)(int);

//这个方法允许模块检查传递给 fnctl(F_SETFL...) 调用的标志.
 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 **);


};

 

llseek() 函数用来修改一个文件的当前读写位置,并将新位置返回,在出错时,这个函数返回一个负值。

read() 函数用来从设备中读取数据,成功时函数返回读取字节数,出错时返回一个负值

write() 函数向设备发送数据,成功时该函数返回写入的字节数。如果此函数未被实现,当用户进行 write() 系统调用时,将得到 -EINVAL 返回值

readdir() 函数仅用于目录,设备点不需要实现它

ioctl() 函数提供设备相关控制命令的实现(既不是读操作也不是写操作),当调用成功时,返回给调用程序一个非负值。内核本身识别部分控制命令,而不必调用设备驱动中的 ioctl()。如果设备不提供 ioctl() 函数,对于内核不能识别的命令,用户进行 ioctl() 系统调用时将获得 -EINVAL 返回值。

mmap() 函数将设备内存映射到进程内存中,如果设备驱动未实现此函数,用户进行 mmap()系统调用时将获得 -ENODEV 返回值。这个函数对于帧缓冲等设备特别有意义。

当用户空间调用 Linux API 函数 open() 打开设备文件时,设备驱动的 open() 函数最终被调用。驱动程序可以不实现这个函数,在这种情况下,设备的打开操作永远成功。与 open() 函数对应的是 release() 函数。

poll() 函数一般用于询问设备是否可被非阻塞地立即读写。当询问的条件未触发时,用户空间进行 select() 和 poll() 系统调用将引起进程的阻塞。

aio_read()  和 aio_write() 函数分别对与文件描述符对应的设备进行异步读、写操作。设备实现这两个函数后,用户空间可以对该设备文件描述符调用 aio_read()、aio_write() 等系统调用进行读写。


http://vicyliu1984.blog.163.com/blog/static/31541232201010773844198/


0 0
原创粉丝点击