f_op也是很重要的!是涉及到所有的文件的操作结构体。例如:用户使用read,最终都会调用file_operations中的读操作,而file_operations结构体是对于不同的文件系统不一定相同。里面一个重要的操作函数是release函数,当用户执行close时候,其实在内核中是执行release函数,这个函数仅仅将f_count减一,这也就解释了上面说的,用户close一个文件其实是将f_count减一。只有引用计数减到0才关闭文件。
注意:对于“正在使用”和“未使用”的文件对象分别使用一个双向链表进行管理。
files_struct
上面的file只是对一个文件而言,对于一个进程(用户)来说,可以同时处理多个文件,所以需要另一个结构来管理所有的files!
即:用户打开文件表--->files_struct
172 struct files_struct {
173
atomic_t count;
174
rwlock_t file_lock;
/* Protects all the below members. Nests inside tsk->alloc_lock */
175
int max_fds;
176
int max_fdset;
177
int next_fd;
178
struct file ** fd;
/* current fd array */
179
fd_set *close_on_exec;
180
fd_set *open_fds;
181
fd_set close_on_exec_init;
182
fd_set open_fds_init;
183
struct file * fd_array[NR_OPEN_DEFAULT];
184 };
解释一些字段:
字段
描述
count
引用计数
file_lock
锁,保护下面的字段
max_fds
当前文件对象的最大的数量
max_fdset
文件描述符最大数
next_fd
已分配的最大的文件描述符+1
fd
指向文件对象指针数组的指针,一般就是指向最后一个字段fd_arrray,当文件数超过NR_OPEN_DEFAULT时候,就会重新分配一个数组,然后指向这个新的数组指针!
close_on_exec
执行exec()时候需要关闭的文件描述符
open_fds
指向打开的文件描述符的指针
close_on_exec_init
执行exec()时候需要关闭的文件描述符初始化值
open_fds_init
文件描述符初值集合
fd_array
文件对象指针的初始化数组
fs_struct
上面的file和files_struct记录的是与进程相关的文件的信息,但是对于进程本身来说,自身的一些信息用什么表示,这里就涉及到fs_struct结构体。
5 struct fs_struct {
6
atomic_t count;
7
rwlock_t lock;
8
int umask;
9
struct dentry * root, * pwd, * altroot;
10
struct vfsmount * rootmnt, * pwdmnt, * altrootmnt;
11 };
解释一些字段:
字段
描述
count
引用计数
lock
保护锁
umask
打开文件时候默认的文件访问权限
root
进程的根目录
pwd
进程当前的执行目录
altroot
用户设置的替换根目录
注意:实际运行时,这三个目录不一定都在同一个文件系统中。例如,进程的根目录通常是安装于“/”节点上的ext文件系统,而当前工作目录可能是安装于/etc的一个文件系统,替换根目录也可以不同文件系统中。
rootmnt,pwdmnt,altrootmnt:对应于上面三个的安装点。
文件方法(操作)file_operations
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);
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
int (*iterate) (struct file *, struct dir_context *);
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);
int (*show_fdinfo)(struct seq_file *m, struct file *f);
};