内核中进程对应的结构为task_struct(/linux-2.6.30/include/linux/sched.h),进程中文件表保存在files中:
struct task_struct {
......
/* open file information */
struct files_struct *files;
....
};
files_struct的结构代码(/linux-2.6.30/include/linux/fdtable.h)如下所示:
/*
* Open file table structure
*/
struct files_struct {
/*
* read mostly part
*/
atomic_t count;
struct fdtable *fdt;
struct fdtable fdtab;
/*
* written part on a separate cache line in SMP
*/
spinlock_t file_lock ____cacheline_aligned_in_smp;
int next_fd;
struct embedded_fd_set close_on_exec_init;
struct embedded_fd_set open_fds_init;
struct file * fd_array[NR_OPEN_DEFAULT];
};
在Linux初始化过程中,对全局变量init_files进行初始化代码(/linux-2.6.30/fs/file.c)如下:
struct files_struct init_files = {
.count = ATOMIC_INIT(1),
.fdt = &init_files.fdtab,
.fdtab = {
.max_fds = NR_OPEN_DEFAULT,
.fd = &init_files.fd_array[0],
.close_on_exec = (fd_set *)&init_files.close_on_exec_init,
.open_fds = (fd_set *)&init_files.open_fds_init,
.rcu = RCU_HEAD_INIT,
},
.file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock),
};
init_files.fdt和init_files.fdtab.fd均分别指向自己已有的成员变量,并以此作为第一个默认值,后边的进程都是从init进程fork出来的。
fork的时候会调用dup_fd,在dup_fd中new_fdt的代码(/linux-2.6.30/fs/file.c)结构如下所示:
/*
* Allocate a new files structure and copy contents from the
* passed in files structure.
* errorp will be valid only when the returned files_struct is NULL.
*/
struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
{
struct files_struct *newf;
struct file **old_fds, **new_fds;
int open_files, size, i;
struct fdtable *old_fdt, *new_fdt;
*errorp = -ENOMEM;
newf = kmem_cache_alloc(files_cachep, GFP_KERNEL);
if (!newf)
goto out;
atomic_set(&newf->count, 1);
spin_lock_init(&newf->file_lock);
newf->next_fd = 0;
new_fdt = &newf->fdtab;
new_fdt->max_fds = NR_OPEN_DEFAULT;
new_fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init;
new_fdt->open_fds = (fd_set *)&newf->open_fds_init;
new_fdt->fd = &newf->fd_array[0];
INIT_RCU_HEAD(&new_fdt->rcu);
new_fdt->next = NULL;
......
}
初始化new_fdt同样是为了让new_fdt和new_fdt->fd指向其本身的成员变量fdtab和fd_array。
初始状态下,files_struct、fdtables和files的关系如下图所示