Linux文件系统之VFS(六)
每个进程都有自己的根目录和当前工作目录,内核使用struct fs_struct
来记录这些信息,进程描述符的fs
字段便是指向该进程的fs_struct
结构。
fs_struct
定义于 include/linux/fs_struct.h
。
struct fs_struct {
int users;
spinlock_t lock;
seqcount_t seq;
int umask;
int in_exec;
struct path root, pwd;
};
除了根目录和当前工作目录,进程还需要记录自己打开的文件。进程已经打开的所有文件使用struct files_struct
来记录,进程描述符的files
字段便指向该进程的files_struct
结构。
files_struct
定义于 include/linux/fdtable.h
.
struct files_struct {
/*
* read mostly part
*/
atomic_t count;
bool resize_in_progress;
wait_queue_head_t resize_wait;
struct fdtable __rcu *fdt;
struct fdtable fdtab;
/*
* written part on a separate cache line in SMP
*/
spinlock_t file_lock ____cacheline_aligned_in_smp;
int next_fd;
unsigned long close_on_exec_init[1];
unsigned long open_fds_init[1];
struct file __rcu * fd_array[NR_OPEN_DEFAULT];
};
由于NR_OPEN_DEFAULT
在x86
结构下的定义为32
,在ia64
结构下的定义为64
,所以说,fd_array
最多只能存储32
或64
个文件对象,远远小于进程被允许打开的最大文件数NR_OPEN
, 如果超过了NR_OPEN_DEFAULT
, 多出来的文件对象将如何存储呢?
显然,内核必须分配新的存储空间存放这些文件对象的指针。旧版本的内核中,struct file_struct
中有一个fd
字段,指向文件对象的指针数组。通常fd
指向fd_array
,如果进程打开的文件数目多于32
个,内核就分配一个新的更大的文件对象的指针数组,并将其地址存放在fd
字段中,这个数组所包含的元素数目存放在max_fds
字段。
新版本的内核将fd
,max_fds
以及其他几个相关字段组织在一起,增加一个新的独立数据结构struct fdtable
,成为文件描述符表,其主要数据结构定义如下所示:
fdtable
定义于 include/linux/fdtable.h
。
struct fdtable {
unsigned int max_fds;
struct file __rcu **fd; /* current fd array */
unsigned long *close_on_exec;
unsigned long *open_fds;
struct rcu_head rcu;
};