open的实现过程

open的实现过程

在这里插入图片描述

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值