linux vfs系統基礎

整體架構圖

clipboard.png
clipboard.png

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]; 
};

clipboard.png

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
};
相關文章
相關標籤/搜索