先说答案:
fd来自task_struct里files_struct类型的fdt中fd数组的下标,不是fd_array数组的下标。
但是,一开始时fd数组就是fd_array数组。
看看下面的结构体:
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;
unsigned int next_fd;
unsigned long close_on_exec_init[1];
unsigned long open_fds_init[1];
unsigned long full_fds_bits_init[1];
struct file __rcu * fd_array[NR_OPEN_DEFAULT];
};
提问:
-
fd_array数组只有32个数组项,但是我们的APP能打开的文件个数超过32,怎么回事?
答:创建进程时,task_struct里files_struct类型的fdt中fd,指向fd_array;当打开的文件个数超过fd_array时,会重新分配更大的数组,fd指向新的数组。 -
所以,我们涉及的都是task_struct里files_struct类型的fdt中fd,不是fd_array
至于fd和file_operations如何绑定,内部过程过于复杂,简单讲讲:
- fd会对应task_struct.files->fdt->fd[fd]的file结构体
- file结构体里有:file_operations成员
- 在哪里设置file结构体的file_operations呢?在内核的一系列的open操作里:
3.1 发现打开的文件是一个特殊的文件(字符设备节点)时,就会设置file->f_op
3.2 函数调用过程太复杂,可以看看这个调用过程:
do_sys_open
do_filp_open
path_openat
do_o_path
vfs_open
do_dentry_open
f->f_op = fops_get(inode->i_fop);