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);
};