整體架構圖
fs_struct
struct fs_struct { atomic_t count; //共享這個表的進程個數 rwlock_t lock; //用於表中字段的讀/寫自旋鎖 int umask; // 當打開文件設置文件權限時所使用的位掩碼 struct dentry *root, //根目錄的目錄項 *pwd, //當前工做目錄的目錄項 *altroot; // struct vfsmount *rootmnt, //根目錄所安裝的文件系統對象 *pwdmnt, // 當前工做目錄所安裝的文件系統對象 *altrootmnt; //模擬根目錄的目錄項(在 80x86 結構上始終爲 NULL) };
struct files_struct
#define NR_OPEN_DEFAULT BITS_PER_LONG #define BITS_PER_LONG 32 /* asm-i386 */ struct files_struct { atomic_t count; // fdtable 就是 APUE第3章 所說的文件描述符表`,fdt初始值指向fdtab struct fdtable *fdt; struct fdtable fdtab; 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地址的數組, 當打開文件數量大於32時,須要構造更多該類型的數組 struct file * fd_array[NR_OPEN_DEFAULT]; };
struct fdtable
文件描述符表
node
struct fdtable { unsigned int max_fds; int max_fdset; struct file ** fd; /* current fd array */ fd_set *close_on_exec; // FD_CLOEXEC標誌 fd_set *open_fds; //當前打開的文件 struct rcu_head rcu; struct files_struct *free_files; struct fdtable *next; };
struct file
文件對象
數組
/*順序打亂,突出重點*/ 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; /* 用於通用文件對象鏈表的指針 */ struct dentry *f_dentry; /* 與文件相關的目錄項對象 */ mode_t f_mode; /* 進程的訪問模式 */ unsigned int f_flags; /* 當打開文件時所指定的標誌 */ loff_t f_pos; /* 當前的文件位移量(文件指針) */ atomic_t f_count; /* 文件對象的引用計數器 */ struct vfsmount *f_vfsmnt; /* 含有該文件的已安裝文件系統 */ const struct file_operations *f_op; /* 指向文件操做表的指針 */ struct fown_struct f_owner; /* 經過信號進行 I/O 事件通知的數據 */ unsigned int f_uid, f_gid; /* 用戶的 UID、 GID */ struct file_ra_state f_ra; /* 文件預讀狀態 */ unsigned long f_version; /* 版本號,每次使用後自動遞增 */ void *f_security; /* 指向文件對象的安全結構的指針 */ /* 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; /* 保護 f_ep_links 鏈表的自旋鎖 */ #endif /* #ifdef CONFIG_EPOLL */ struct address_space *f_mapping; /* 指向文件地址空間對象的指針 */ };
struct dentry
每一個目錄看做由若干子目錄和文件組成的一個普通文件。
然而目錄項不一樣,一旦目錄項被讀入內存, VFS 就把它轉換成基於dentry結構的一個目錄項對象。
對於進程查找的路徑名中的每一個份量,內核都爲其建立一個目錄項對象;
緩存
struct dentry { atomic_t d_count; /* 目錄項對象引用計數器 */ unsigned int d_flags; /* 目錄項高速緩存標誌 */ spinlock_t d_lock; /* 保護目錄項對象的自旋鎖 */ struct inode *d_inode; /* 與文件名關聯的索引節點*/ struct qstr d_name; /* 文件名 */ struct list_head d_subdirs; /* 對目錄而言,子目錄項鍊表的頭 */ /* The next three fields are touched by __d_lookup. Place them here * so they all fit in a cache line. */ struct hlist_node d_hash; /* 指向散列表表項鍊表的指針 */ struct dentry *d_parent; /* 父目錄的目錄項對象 */ struct list_head d_lru; /* 用於未使用目錄項鍊表的指針 */ /* * d_child and d_rcu can share memory */ union { struct list_head d_child; /* 對目錄而言,用於同一父目錄中的目錄項鍊表的指針 */ struct rcu_head d_rcu; /* 回收目錄項對象時,由 RCU 描述符使用 */ } d_u; struct list_head d_alias; /* 用於與同一索引節點(別名)相關的目錄項鍊表的指針 */ unsigned long d_time; /* 由 d_revalidate 方法使用 */ struct dentry_operations *d_op; /* 目錄項方法 */ struct super_block *d_sb; /* 文件的超級塊對象 */ void *d_fsdata; /* 依賴於文件系統的數據 */ void *d_extra_attributes; /* TUX-specific data */ #ifdef CONFIG_PROFILING struct dcookie_struct *d_cookie; /* cookie,指向內核配置文件使用的數據結構的指針*/ #endif int d_mounted; /* 對目錄而言,用於記錄安裝該目錄項的文件系統數的計數器 */ unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* 存放短文件名的空間 */ };
struct node
struct inode { struct hlist_node i_hash; /* 用於散列鏈表的指針 */ struct list_head i_list; /* 用於描述索引節點當前狀態的鏈表的指針 */ struct list_head i_sb_list; /* 用於超級塊的索引節點鏈表的指針 */ struct list_head i_dentry; /* 引用索引節點的目錄項對象鏈表的頭 */ unsigned long i_ino; /* 索引節點號 */ atomic_t i_count; /* 引用計數器 */ umode_t i_mode; /* 文件類型與訪問權限 */ unsigned int i_nlink; /* 硬連接數目 */ loff_t i_size; /* 文件的字節數 */ uid_t i_uid; /* 全部者標識符 */ gid_t i_gid; /* 全部者組標識符 */ dev_t i_rdev; /* 實設備標識符 */ struct timespec i_atime; /* 上次訪問文件的時間 */ struct timespec i_mtime; /* 上次寫文件的時間 */ struct timespec i_ctime; /* 上次修改索引節點的時間 */ unsigned int i_blkbits; /* 塊的位數 */ unsigned long i_version; /* 版本號(每次使用後自動遞增) */ blkcnt_t i_blocks; /* 文件的塊數 */ unsigned short i_bytes; /* 文件中最後一個塊的字節數 */ spinlock_t i_lock; /* 保護索引節點一些字段的自旋鎖: i_blocks, i_bytes, maybe i_size */ struct mutex i_mutex; /* 索引節點信號量 */ struct rw_semaphore i_alloc_sem; /* 在直接 I/O 文件操做中避免出現競爭條件的讀/寫信號量 */ struct inode_operations *i_op; /* 索引節點的操做 */ const struct file_operations *i_fop; /* 缺省文件操做: former->i_op->default_file_ops */ struct super_block *i_sb; /* 指向超級塊對象的指針 */ struct file_lock *i_flock; /* 指向文件鎖鏈表的指針 */ struct address_space *i_mapping; /* 指向緩存 address_space 對象的指針 */ struct address_space i_data; /* 嵌入在 inode 中的文件的 address_space 對象 */ #ifdef CONFIG_QUOTA struct dquot *i_dquot[MAXQUOTAS]; /* 索引節點磁盤限額 */ #endif struct list_head i_devices; /* 用於具體的字符或塊設備索引節點鏈表的指針 */ union { struct pipe_inode_info *i_pipe; /* 若是文件是一個管道則使用它 */ struct block_device *i_bdev; /* 指向塊設備驅動程序的指針 */ struct cdev *i_cdev; /* 指向字符設備驅動程序的指針 */ }; int i_cindex; /* 擁有一組次設備號的設備文件的索引 */ __u32 i_generation; /* 索引節點版本號(由某些文件系統使用) */ #ifdef CONFIG_DNOTIFY unsigned long i_dnotify_mask; /* 目錄通知事件的位掩碼 */ struct dnotify_struct *i_dnotify; /* 用於目錄通知 */ #endif #ifdef CONFIG_INOTIFY struct list_head inotify_watches; /* watches on this inode */ struct mutex inotify_mutex; /* protects the watches list */ #endif unsigned long i_state; /* 索引節點的狀態標誌 */ unsigned long dirtied_when; /* 索引節點的弄髒時間(以節拍爲單位) */ unsigned int i_flags; /* 文件系統的安裝標誌 */ atomic_t i_writecount; /* 用於寫進程的引用計數器 */ void *i_security; /* 指向索引節點安全結構的指針 */ void *i_private; /* 指向私有數據的指針 */ #ifdef __NEED_I_SIZE_ORDERED seqcount_t i_size_seqcount;/* SMP 系統爲 i_size 字段獲取一致值時使用的順序計數器 */ #endif };