文件描述符fd、文件索引節點inode、文件對象file關系
- 1 VFS對象
- 1.1 超級塊對象
- 1.2 索引節點對象
- 1.3 文件對象
- 1.4 進程描述符
- 1.5 files_struct
- 2 如何根據文件描述符fd找到文件?
1 VFS對象
在說fd、inode和file關系之前,我們先了解VFS的幾個概念。分別是進程描述符、超級塊對象、索引節點和文件對象。
1.1 超級塊對象
超級塊對象代表一個已安裝的文件系統,由super_block
結構體表示,定義在文件linux/fs中。
1.2 索引節點對象
索引節點對象代表一個具體文件,由struct inode
結構體表示,定義在linux/fs.h中。
1.3 文件對象
文件對象表示一個進程已經打開的文件。由struct file
結構體表示,定義在linux/fs.h中。
struct file {...struct inode *f_inode; /* cached value */const struct file_operations *f_op;...
};
f_inode指向一個具體文件。
1.4 進程描述符
進程描述符來代表一個進程,由結構體struct task_struct
表示,該結構定義在include/linux/sched.h文件中。
struct task_struct {.../* open file information */struct files_struct *files;...
};
我們要注意files域,該域指向一個進程打開的所有文件。
1.5 files_struct
files_struct表示一個進程打開的所有文件,files_struct
結構體定義在文件linux/fdtable.h中。該結構體由進程描述符中的files域指向。所有與每個進程打開的文件及文件描述符都包含在其中,其結構體描述如下:
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];
};
struct fdtable
結構體如下:
struct fdtable {unsigned int max_fds;struct file __rcu **fd; /* current fd array */unsigned long *close_on_exec;unsigned long *open_fds;unsigned long *full_fds_bits;struct rcu_head rcu;
};
fd域指向的就是進程打開的文件,它實際是個數組,fd數組指針指向已打開的文件對象鏈表,默認情況下,指向fd_array數組,NR_OPEN_DEFAULT是個定值,當一個進程打開的文件對象超過NR_OPEN_DEFAULT時,內核將分配一個新數組,并且用fd指針指向它。
文件描述符fd就是索引值,在fd數組中找到文件對象。
2 如何根據文件描述符fd找到文件?
我們用write的系統調用來分析如何找到文件的,
首先會文件文件描述符fd獲取結構體類型struct fd
struct fd f = fdget_pos(fd);struct fd {struct file *file;unsigned int flags;
};
fdget_pos函數中會調用很多很函數,它會先用當前進程current找到files域,然后在files中找到struct fdtable類型指針fdt,在fdt里面找到指向文件對象的fd數組,fd數組根據文件描述符fd(索引)找到進程打開的文件對象,最后返回。
fdget_pos返回的是一個struct fd結構體,這個結構體里面就是我們找到的文件對象,后面就可以根據這個文件對象找到文件的索引節點。
注意:文件對象代表的是進程打開的文件,索引節點代表的是真正的文件,可能有多個不同進程的文件對象指向同一個索引節點