open的实现过程
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/1c6a24df32aba0a5e6dc5510b0df8f11.png)
struct task_struct {
...
/* 文件系统信息 */
/* 用于在查找环形链表时防止无限循环 */
int link_cont, total_link_count;
...
/* 文件系统信息 */
struct fs_struct *fs;
/* 打开文件信息,包含进程的各个文件描述符 */
struct files_struct *files;
/* 命名空间 */
struct nsproxy *nsproxy;
...
}
struct files_struct {
/*
* read mostly part
*/
atomic_t count;
/* 多包含一个fatable的指针是用于RCU */
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实例(下给出了详细结构), 如果进程试图打开比NR_OPEN_DEFAULT
更多的文件,内核必须对files_struct中用于管理与进程相关的所有文件信息的各个成员
分配更多的内存空间,最重要的是fdtable
*/
struct file * fd_array[NR_OPEN_DEFAULT];
};
/*
* The embedded_fd_set is a small fd_set,
* suitable for most tasks (which open <= BITS_PER_LONG files)
*/
struct embedded_fd_set {
unsigned long fds_bits[1];
};
/* 初看起来,fdtable和files_struct之间某些信息似乎是重复的,其实fdtable中的成员
都是指针,初始时都指向了后者的对应成员, 当需要打开的文件超过了NR_OPEN_DEFAULT时
,内核会分配一个fd_set的实例, 替换最初的embedded_fd_set*/
struct fdtable {
/* 进程当前可以处理的文件对象和文件描述符的最大数目 */
unsigned int max_fds;
/* 指针数组,每个数组项管理一个打开文件的所有信息, 文件描述符充当数组索引,长度由max_fds定义 */
struct file ** fd; /* current fd array */
fd_set *close_on_exec;
/* 指向管理所有打开文件描述符的位域,bit置位标示文件描述符在使用中 */
fd_set *open_fds;
struct rcu_head rcu;
struct fdtable *next;
};
struct file {
/*
* fu_list becomes invalid after file_free is called and queued via
* fu_rcuhead for RCU freeing
*/
union {
struct list_head fu_list;
struct rcu_head fu_rcuhead;
} f_u;
/* 封装了:
1. 文件名和inode之间的关联
2. 文件所在文件系统的信息
后面代码给出了详细结构*/
struct path f_path;
#define f_dentry f_path.dentry
#define f_vfsmnt f_path.mnt
/* 文件操作 */
const struct file_operations *f_op;
atomic_t f_count;
/* open系统调用传递的额外标志 */
unsigned int f_flags;
mode_t f_mode;
/* 文件位置当前值 */
loff_t f_pos;
/* 处理该文件的进程有关的信息 */
struct fown_struct f_owner;
unsigned int f_uid, f_gid;
/* 预读特征,指定是否预读,如何预读*/
struct file_ra_state f_ra;
/* 用于文件系统检查一个file实例是否仍然与相关的inode内容兼容,
这对于确保已缓存对象的一致性很重要 */
u64 f_version;
#ifdef CONFIG_SECURITY
void *f_security;
#endif
/* needed for tty driver, and maybe others */
void *private_data;
#ifdef CONFIG_EPOLL
/* Used by fs/eventpoll.c to link all the hooks to this file */
struct list_head f_ep_links;
spinlock_t f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */
/* 属于文件相关的inode实例的地址空间映射 */
struct address_space *f_mapping;
};
struct path {
/* 所在文件系统 */
struct vfsmount *mnt;
/* 提供文件名与inode之间的关联 */
struct dentry *dentry;
};
struct fs_struct {
atomic_t count;
rwlock_t lock;
/* 新文件权限 */
int umask;
/* 根目录,当前目录,个性 */
struct dentry * root, * pwd, * altroot;
/* 上面目录对应的文件系统 */
struct vfsmount * rootmnt, * pwdmnt, * altrootmnt;
};
#+DOWNLOADED: screenshot @ 2020-11-18 16:12:04