- 和文件系统相关的数据结构
内核使用一些标准数据结构来管理文件系统的其他相关数据。结构体file_system_type,用于描述各种特定的文件系统类型:
- 在<Fs.h(include/linux)>中
- struct file_system_type {
- const char *name;
- int fs_flags;
- /*该函数从磁盘上读取超级块,并在文件系统被安装时,在内存中组装超级块对象*/
- int (*get_sb) (struct file_system_type *, int,
- const char *, void *, struct vfsmount *);
- void (*kill_sb) (struct super_block *);
- struct module *owner;
- struct file_system_type * next;
- struct list_head fs_supers;
- struct lock_class_key s_lock_key;
- struct lock_class_key s_umount_key;
- };
每种文件系统,不管有多少个实例安装到系统中,还是根本没有安装到系统中,都只有一个file_system_type结构。
结构体vfsmount用于描述一个安装文件系统的实例:
- 在<Mount.h(include/linux)>中
- struct vfsmount {
- struct list_head mnt_hash;
- struct vfsmount *mnt_parent; /* fs we are mounted on */
- struct dentry *mnt_mountpoint; /* dentry of mountpoint */
- struct dentry *mnt_root; /* root of the mounted tree */
- struct super_block *mnt_sb; /* pointer to superblock */
- struct list_head mnt_mounts; /* list of children, anchored here */
- struct list_head mnt_child; /* and going through their mnt_child */
- int mnt_flags;
- /* 4 bytes hole on 64bits arches */
- char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
- struct list_head mnt_list;
- struct list_head mnt_expire; /* link in fs-specific expiry list */
- struct list_head mnt_share; /* circular list of shared mounts */
- struct list_head mnt_slave_list;/* list of slave mounts */
- struct list_head mnt_slave; /* slave list entry */
- struct vfsmount *mnt_master; /* slave is on master->mnt_slave_list */
- struct mnt_namespace *mnt_ns; /* containing namespace */
- /*
- * We put mnt_count & mnt_expiry_mark at the end of struct vfsmount
- * to let these frequently modified fields in a separate cache line
- * (so that reads of mnt_flags wont ping-pong on SMP machines)
- */
- atomic_t mnt_count;
- int mnt_expiry_mark; /* true if marked for expiry */
- int mnt_pinned;
- };
当文件系统被实际安装时,将有一个vfsmount结构体在安装点被创建。该结构体用来代表文件系统的示例,即代表一个安装点。
vfsmount结构体中保存了在安装时指定的标志信息,这些信息存储在mnt_flags域中:
- #define MNT_NOSUID 0x01 //禁止该文件系统的可执行文件执行文件设置setuid和setgid
- #define MNT_NODEV 0x02 //禁止访问该文件系统上的设备文件
- #define MNT_NOEXEC 0x04 //禁止执行该文件系统上的可执行文件
- #define MNT_NOATIME 0x08
- #define MNT_NODIRATIME 0x10
- #define MNT_RELATIME 0x20
- 和进程相关的数据结构
系统中的每一个进程都有自己的一组打开文件,像根文件系统、当前工作目录、安装点等。有三个数据结构将VFS层和进程紧密联系在一起:files_struct,fs_struc和namespace结构体。
files_struct结构体由进程描述符中的files域指向。所有与每个进程(per-process)相关的信息如打开的文件及文件描述符都包含在其中:
- 在<Files.h(include/linux)>中
- /*
- * The default fd array needs to be at least BITS_PER_LONG,
- * as this is the granularity returned by copy_fdset().
- */
- #define NR_OPEN_DEFAULT BITS_PER_LONG
- /*
- * 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];
- };
- struct fdtable {
- unsigned int max_fds;
- struct file ** fd; /* current fd array fd数组指针指向已打开的文件对象链表,默认情况下,指向fd_array数组。 */
- fd_set *close_on_exec;
- fd_set *open_fds;
- struct rcu_head rcu;
- struct fdtable *next;
- };
- /*
- * Open file table structure
- */
- struct files_struct {
- /*
- * read mostly part
- */
- atomic_t count;
- 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 * fd_array[NR_OPEN_DEFAULT];
- };
fs_struct结构体由进程描述符中的fs域指向。它包含文件系统和进程相关的信息:
- 在<Fs_struc.h>中
- struct dentry;
- struct vfsmount;
- struct fs_struct {
- atomic_t count;
- rwlock_t lock;
- int umask;
- struct dentry * root, * pwd, * altroot;
- struct vfsmount * rootmnt, * pwdmnt, * altrootmnt;
- };
namespace结构体由进程描述符中的namespace域指向。2.4版内核之后,单进程命名空间被加入到内核中,它使得每一个进程在系统中都看到唯一的安装文件系统,不仅是惟一的根目录,而且是惟一的文件系统层次结构:
- 没有找到nampspace.h文件,所以在<mnt_namespace.h(include/linux)>中找到下面的结构:
- struct mnt_namespace {
- atomic_t count;
- struct vfsmount * root;
- struct list_head list;
- wait_queue_head_t poll;
- int event;
- };
上述数据结构都是通过进程描述符连接起来的。对多数进程来说,它们的描述符都指向唯一的files_struct和fs_struct结构体。所以多个进程描述符可能指向同一个files_struct和fs_struct结构体。
默认情况下,所有的进程共享同样的命名空间(即它们都从相同的挂载表中看到同一个文件系统层次结构)。只有在进行CLONE_NEWNS标志,才会给进程一个另外的命名空间结构体的拷贝。