- 和文件系統相關的數據結構
內核使用一些標準數據結構來管理文件系統的其他相關數據。結構體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標誌,纔會給進程一個另外的命名空間結構體的拷貝。