虚拟文件系统[6]

来源:互联网 发布:流量话费充值分销源码 编辑:程序博客网 时间:2024/06/06 06:59
  • 和文件系统相关的数据结构

     内核使用一些标准数据结构来管理文件系统的其他相关数据。结构体file_system_type,用于描述各种特定的文件系统类型:

 

  1. 在<Fs.h(include/linux)>中
  2. struct file_system_type {
  3.     const char *name;
  4.     int fs_flags;
  5.       /*该函数从磁盘上读取超级块,并在文件系统被安装时,在内存中组装超级块对象*/
  6.     int (*get_sb) (struct file_system_type *, int,
  7.                const char *, void *, struct vfsmount *);
  8.     void (*kill_sb) (struct super_block *);
  9.     struct module *owner;
  10.     struct file_system_type * next;
  11.     struct list_head fs_supers;
  12.     struct lock_class_key s_lock_key;
  13.     struct lock_class_key s_umount_key;
  14. };

     每种文件系统,不管有多少个实例安装到系统中,还是根本没有安装到系统中,都只有一个file_system_type结构。
    结构体vfsmount用于描述一个安装文件系统的实例:

  1. 在<Mount.h(include/linux)>中
  2. struct vfsmount {
  3.     struct list_head mnt_hash;
  4.     struct vfsmount *mnt_parent;    /* fs we are mounted on */
  5.     struct dentry *mnt_mountpoint;  /* dentry of mountpoint */
  6.     struct dentry *mnt_root;    /* root of the mounted tree */
  7.     struct super_block *mnt_sb; /* pointer to superblock */
  8.     struct list_head mnt_mounts;    /* list of children, anchored here */
  9.     struct list_head mnt_child; /* and going through their mnt_child */
  10.     int mnt_flags;
  11.     /* 4 bytes hole on 64bits arches */
  12.     char *mnt_devname;      /* Name of device e.g. /dev/dsk/hda1 */
  13.     struct list_head mnt_list;
  14.     struct list_head mnt_expire;    /* link in fs-specific expiry list */
  15.     struct list_head mnt_share; /* circular list of shared mounts */
  16.     struct list_head mnt_slave_list;/* list of slave mounts */
  17.     struct list_head mnt_slave; /* slave list entry */
  18.     struct vfsmount *mnt_master;    /* slave is on master->mnt_slave_list */
  19.     struct mnt_namespace *mnt_ns;   /* containing namespace */
  20.     /*
  21.      * We put mnt_count & mnt_expiry_mark at the end of struct vfsmount
  22.      * to let these frequently modified fields in a separate cache line
  23.      * (so that reads of mnt_flags wont ping-pong on SMP machines)
  24.      */
  25.     atomic_t mnt_count;
  26.     int mnt_expiry_mark;        /* true if marked for expiry */
  27.     int mnt_pinned;
  28. };

   当文件系统被实际安装时,将有一个vfsmount结构体在安装点被创建。该结构体用来代表文件系统的示例,即代表一个安装点。

   vfsmount结构体中保存了在安装时指定的标志信息,这些信息存储在mnt_flags域中:

  1. #define MNT_NOSUID  0x01      //禁止该文件系统的可执行文件执行文件设置setuid和setgid
  2. #define MNT_NODEV   0x02      //禁止访问该文件系统上的设备文件
  3. #define MNT_NOEXEC  0x04      //禁止执行该文件系统上的可执行文件
  4. #define MNT_NOATIME 0x08
  5. #define MNT_NODIRATIME  0x10
  6. #define MNT_RELATIME    0x20
  • 和进程相关的数据结构

   系统中的每一个进程都有自己的一组打开文件,像根文件系统、当前工作目录、安装点等。有三个数据结构将VFS层和进程紧密联系在一起:files_struct,fs_struc和namespace结构体。

   files_struct结构体由进程描述符中的files域指向。所有与每个进程(per-process)相关的信息如打开的文件及文件描述符都包含在其中:

 

  1. 在<Files.h(include/linux)>中
  2. /*
  3.  * The default fd array needs to be at least BITS_PER_LONG,
  4.  * as this is the granularity returned by copy_fdset().
  5.  */
  6. #define NR_OPEN_DEFAULT BITS_PER_LONG
  7. /*
  8.  * The embedded_fd_set is a small fd_set,
  9.  * suitable for most tasks (which open <= BITS_PER_LONG files)
  10.  */
  11. struct embedded_fd_set {
  12.     unsigned long fds_bits[1];
  13. };
  14. struct fdtable {
  15.     unsigned int max_fds;
  16.     struct file ** fd;      /* current fd array   fd数组指针指向已打开的文件对象链表,默认情况下,指向fd_array数组。  */
  17.     fd_set *close_on_exec;
  18.     fd_set *open_fds;
  19.     struct rcu_head rcu;
  20.     struct fdtable *next;
  21. };
  22. /*
  23.  * Open file table structure
  24.  */
  25. struct files_struct {
  26.   /*
  27.    * read mostly part
  28.    */
  29.     atomic_t count;
  30.     struct fdtable *fdt;
  31.     struct fdtable fdtab;
  32.   /*
  33.    * written part on a separate cache line in SMP
  34.    */
  35.     spinlock_t file_lock ____cacheline_aligned_in_smp;
  36.     int next_fd;
  37.     struct embedded_fd_set close_on_exec_init;
  38.     struct embedded_fd_set open_fds_init;
  39.     struct file * fd_array[NR_OPEN_DEFAULT];
  40. };

 

  fs_struct结构体由进程描述符中的fs域指向。它包含文件系统和进程相关的信息:

 

 

  1. 在<Fs_struc.h>中
  2. struct dentry;
  3. struct vfsmount;
  4. struct fs_struct {
  5.     atomic_t count;
  6.     rwlock_t lock;
  7.     int umask;
  8.     struct dentry * root, * pwd, * altroot;
  9.     struct vfsmount * rootmnt, * pwdmnt, * altrootmnt;
  10. };

  namespace结构体由进程描述符中的namespace域指向。2.4版内核之后,单进程命名空间被加入到内核中,它使得每一个进程在系统中都看到唯一的安装文件系统,不仅是惟一的根目录,而且是惟一的文件系统层次结构:

 

  1. 没有找到nampspace.h文件,所以在<mnt_namespace.h(include/linux)>中找到下面的结构:
  2. struct mnt_namespace {
  3.     atomic_t        count;
  4.     struct vfsmount *   root;
  5.     struct list_head    list;
  6.     wait_queue_head_t poll;
  7.     int event;
  8. };

   上述数据结构都是通过进程描述符连接起来的。对多数进程来说,它们的描述符都指向唯一的files_struct和fs_struct结构体。所以多个进程描述符可能指向同一个files_struct和fs_struct结构体。

   默认情况下,所有的进程共享同样的命名空间(即它们都从相同的挂载表中看到同一个文件系统层次结构)。只有在进行CLONE_NEWNS标志,才会给进程一个另外的命名空间结构体的拷贝。