Linux文件系統2---VFS的四個主要對象


1.引言

本文所述關於文件管理的系列文章主要是對陳莉君老師所講述的文件系統管理知識講座的整理。

Linux可以支持不同的文件系統,它源於unix文件系統,也是unix文件系統的一大特色。

Linux文件系統1--概述 中我們了解了文件系統的作用,以及為了使得所有的文件系統能在同一個操作系統上工作,而產生的虛擬文件系統。

本章我們開始分析萬能的虛擬文件系統是怎么構成的,虛擬文件文件系統由四個主要的對象構成,分別是:超級塊,索引結點,目錄項,文件對象。

而所謂的文件系統主要是對文件對象進行管理,那么,其余的三個結構體是用來做什么的呢?

想一下,如果,你要查一份文件,必須要核對文件對象,那么文件對象越大,CPU則會浪費很多時間在核對上。

所以,我們給文件對象學着外國人一樣, 起了三層結構的名字,目錄項--索引結點--超級塊,是不是很有趣。

2.文件系統的四個主要對象概述

  • 超級塊對象

存放系統中已安裝文件系統的信息

  • 索引節點對象

存放關於具體文件的一般信息

  • 目錄項對象

存放目錄項與對應文件進行鏈接的信息

  • 文件對象

存放打開文件與進程之間進行交互的有關信息

3. 超級塊super_block

3.1 struct super_block

  1 struct super_block {
  2     struct list_head    s_list;        /* Keep this first 指向超級塊鏈表的指針*/
  3     dev_t            s_dev;        /* search index; _not_ kdev_t 具體文件系統的塊設備描述符*/
  4     unsigned char        s_blocksize_bits;
  5     unsigned long        s_blocksize; /*以字節為單位的數據塊的大小*/
  6     loff_t            s_maxbytes;    /* Max file size */
  7     struct file_system_type    *s_type; /*文件系統類型*/
  8     const struct super_operations    *s_op; /*指向超級塊操作的函數集合*/
  9     const struct dquot_operations    *dq_op;
 10     const struct quotactl_ops    *s_qcop;
 11     const struct export_operations *s_export_op;
 12     unsigned long        s_flags;
 13     unsigned long        s_iflags;    /* internal SB_I_* flags */
 14     unsigned long        s_magic;
 15     struct dentry        *s_root;
 16     struct rw_semaphore    s_umount;
 17     int            s_count;
 18     atomic_t        s_active;
 19 #ifdef CONFIG_SECURITY
 20     void                    *s_security;
 21 #endif
 22     const struct xattr_handler **s_xattr;
 23 
 24     struct hlist_bl_head    s_anon;        /* anonymous dentries for (nfs) exporting */
 25     struct list_head    s_mounts;    /* list of mounts; _not_ for fs use */
 26     struct block_device    *s_bdev;
 27     struct backing_dev_info *s_bdi;
 28     struct mtd_info        *s_mtd;
 29     struct hlist_node    s_instances;
 30     unsigned int        s_quota_types;    /* Bitmask of supported quota types */
 31     struct quota_info    s_dquot;    /* Diskquota specific options */
 32 
 33     struct sb_writers    s_writers;
 34 
 35     char s_id[32];                /* Informational name */
 36     u8 s_uuid[16];                /* UUID */
 37 
 38     void             *s_fs_info;    /* Filesystem private info 具體文件系統的私有數據*/
 39     unsigned int        s_max_links;
 40     fmode_t            s_mode;
 41 
 42     /* Granularity of c/m/atime in ns.
 43        Cannot be worse than a second */
 44     u32           s_time_gran;
 45 
 46     /*
 47      * The next field is for VFS *only*. No filesystems have any business
 48      * even looking at it. You had been warned.
 49      */
 50     struct mutex s_vfs_rename_mutex;    /* Kludge */
 51 
 52     /*
 53      * Filesystem subtype.  If non-empty the filesystem type field
 54      * in /proc/mounts will be "type.subtype"
 55      */
 56     char *s_subtype;
 57 
 58     /*
 59      * Saved mount options for lazy filesystems using
 60      * generic_show_options()
 61      */
 62     char __rcu *s_options;
 63     const struct dentry_operations *s_d_op; /* default d_op for dentries */
 64 
 65     /*
 66      * Saved pool identifier for cleancache (-1 means none)
 67      */
 68     int cleancache_poolid;
 69 
 70     struct shrinker s_shrink;    /* per-sb shrinker handle */
 71 
 72     /* Number of inodes with nlink == 0 but still referenced */
 73     atomic_long_t s_remove_count;
 74 
 75     /* Being remounted read-only */
 76     int s_readonly_remount;
 77 
 78     /* AIO completions deferred from interrupt context */
 79     struct workqueue_struct *s_dio_done_wq;
 80     struct hlist_head s_pins;
 81 
 82     /*
 83      * Keep the lru lists last in the structure so they always sit on their
 84      * own individual cachelines.
 85      */
 86     struct list_lru        s_dentry_lru ____cacheline_aligned_in_smp;
 87     struct list_lru        s_inode_lru ____cacheline_aligned_in_smp;
 88     struct rcu_head        rcu;
 89     struct work_struct    destroy_work;
 90 
 91     struct mutex        s_sync_lock;    /* sync serialisation lock */
 92 
 93     /*
 94      * Indicates how deep in a filesystem stack this SB is
 95      */
 96     int s_stack_depth;
 97 
 98     /* s_inode_list_lock protects s_inodes */
 99     spinlock_t        s_inode_list_lock ____cacheline_aligned_in_smp;
100     struct list_head    s_inodes;    /* all inodes 所有的inodes*/
101 };
  • 超級塊用來描述整個文件系統的信息
  • 每個具體的文件系統都有自己的超級塊
  • VFS超級塊是各種文件系統在安裝時建立的,並在卸載時被自動刪除,其數據結構是super_block
  • 所有超級塊對象都以雙向循環鏈表的形式鏈接在一起

圖 所有超級塊鏈接在一起

 

3.2 struct super_operations

圖 超級塊對象的操作函數

  • 與超級塊關聯的方法就是超級塊操作表,這些操作是由struct super_operations來描述

3.3 打印超級塊信息

 

4.索引節點inode

 4.1 struct inode

 1 struct inode {
 2     umode_t            i_mode;
 3     unsigned short        i_opflags;
 4     kuid_t            i_uid;
 5     kgid_t            i_gid;
 6     unsigned int        i_flags;
 7 
 8 #ifdef CONFIG_FS_POSIX_ACL
 9     struct posix_acl    *i_acl;
10     struct posix_acl    *i_default_acl;
11 #endif
12 
13     const struct inode_operations    *i_op;
14     struct super_block    *i_sb;
15     struct address_space    *i_mapping;
16 
17 #ifdef CONFIG_SECURITY
18     void            *i_security;
19 #endif
20 
21     /* Stat data, not accessed from path walking */
22     unsigned long        i_ino;
23     /*
24      * Filesystems may only read i_nlink directly.  They shall use the
25      * following functions for modification:
26      *
27      *    (set|clear|inc|drop)_nlink
28      *    inode_(inc|dec)_link_count
29      */
30     union {
31         const unsigned int i_nlink;
32         unsigned int __i_nlink;
33     };
34     dev_t            i_rdev;
35     loff_t            i_size;
36     struct timespec        i_atime;
37     struct timespec        i_mtime;
38     struct timespec        i_ctime;
39     spinlock_t        i_lock;    /* i_blocks, i_bytes, maybe i_size */
40     unsigned short          i_bytes;
41     unsigned int        i_blkbits;
42     blkcnt_t        i_blocks;
43 
44 #ifdef __NEED_I_SIZE_ORDERED
45     seqcount_t        i_size_seqcount;
46 #endif
47 
48     /* Misc */
49     unsigned long        i_state; /*索引節點的狀態標志*/
50     struct mutex        i_mutex;
51 
52     unsigned long        dirtied_when;    /* jiffies of first dirtying */
53     unsigned long        dirtied_time_when;
54 
55     struct hlist_node    i_hash; /*指向哈希鏈表的指針*/
56     struct list_head    i_io_list;    /* backing dev IO list */
57 #ifdef CONFIG_CGROUP_WRITEBACK
58     struct bdi_writeback    *i_wb;        /* the associated cgroup wb */
59 
60     /* foreign inode detection, see wbc_detach_inode() */
61     int            i_wb_frn_winner;
62     u16            i_wb_frn_avg_time;
63     u16            i_wb_frn_history;
64 #endif
65     struct list_head    i_lru;        /* inode LRU list 指向索引節點鏈表的指針*/
66     struct list_head    i_sb_list; /*指向超級塊的指針*/
67     union {
68         struct hlist_head    i_dentry;
69         struct rcu_head        i_rcu;
70     };
71     u64            i_version;
72     atomic_t        i_count;
73     atomic_t        i_dio_count;
74     atomic_t        i_writecount;
75 #ifdef CONFIG_IMA
76     atomic_t        i_readcount; /* struct files open RO */
77 #endif
78     const struct file_operations    *i_fop;    /* former ->i_op->default_file_ops */
79     struct file_lock_context    *i_flctx;
80     struct address_space    i_data;
81     struct list_head    i_devices;
82     union {
83         struct pipe_inode_info    *i_pipe;
84         struct block_device    *i_bdev;
85         struct cdev        *i_cdev;
86         char            *i_link;
87     };
88 
89     __u32            i_generation;
90 
91 #ifdef CONFIG_FSNOTIFY
92     __u32            i_fsnotify_mask; /* all events this inode cares about */
93     struct hlist_head    i_fsnotify_marks;
94 #endif
95 
96     void            *i_private; /* fs or device private pointer */
97 };

 

  • 文件系統處理文件所需要的所有信息都保存在稱為索引節點的inode結構體中
  • 同一個文件系統中,每個文件的索引節點號都是唯一的
  • 與索引節點關聯的方法由struct inode_operations來描述
  • inode有兩個設備號:i_dev(常規文件的設備號),i_rdev(某一設備的設備號)
  • LInux文件系統的另外一大特色:設備即文件。驅動中設備號的來源

 4.2  struct inode_operations

圖 索引節點的操作函數

5.目錄項dentry

5.1 struct dentry

84    struct dentry {
85        /* RCU lookup touched fields */
86        unsigned int d_flags;        /* protected by d_lock */
87        seqcount_t d_seq;        /* per dentry seqlock */
88        struct hlist_bl_node d_hash;    /* lookup hash list */
89        struct dentry *d_parent;    /* parent directory */
90        struct qstr d_name;
91        struct inode *d_inode;        /* Where the name belongs to - NULL is
92                         * negative */
93        unsigned char d_iname[DNAME_INLINE_LEN];    /* small names */
94    
95        /* Ref lookup also touches following */
96        struct lockref d_lockref;    /* per-dentry lock and refcount */
97        const struct dentry_operations *d_op;
98        struct super_block *d_sb;    /* The root of the dentry tree */
99        unsigned long d_time;        /* used by d_revalidate */
100        void *d_fsdata;            /* fs-specific data */
101    
102        union {
103            struct list_head d_lru;        /* LRU list */
104            wait_queue_head_t *d_wait;    /* in-lookup ones only */
105        };
106        struct list_head d_child;    /* child of parent list */
107        struct list_head d_subdirs;    /* our children */
108        /*
109         * d_alias and d_rcu can share memory
110         */
111        union {
112            struct hlist_node d_alias;    /* inode alias list */
113            struct hlist_bl_node d_in_lookup_hash;    /* only for in-lookup ones */
114             struct rcu_head d_rcu;
115        } d_u;
116    };

 

  • 每個文件除了一個struct inode結構體外,還要一個目錄項struct dentry結構
  • dentry代表的邏輯意義上的文件,描述的是文件邏輯上的屬性,目錄項對象在磁盤上並沒有對應的映像
  • inode代表的是物理意義上的文件,記錄的是物理上的屬性,對於一個具體的文件系統,其inode在磁盤上有對應的映像
  • 一個索引節點可能對應多個目錄項對象

5.2  struct dentry_operations

圖 目錄項的操作函數

6. 文件對象(file)

 

6.1 struct file

struct file {
836        union {
837            struct llist_node    fu_llist;//文件對象鏈表
838            struct rcu_head     fu_rcuhead; //釋放之后的RCU鏈表
839        } f_u;
840        struct path        f_path;
841        struct inode        *f_inode;    /* cached value */
842        const struct file_operations    *f_op;
843    
844        /*
845         * Protects f_ep_links, f_flags.
846         * Must not be taken from IRQ context.
847         */
848        spinlock_t        f_lock;
849        atomic_long_t        f_count;   //文件對象的使用計數
850        unsigned int         f_flags;  //當打開文件時所使用的標志
851        fmode_t            f_mode;     //文件的訪問模式
852        struct mutex        f_pos_lock;
853        loff_t            f_pos;       //文件當前的位移量
854        struct fown_struct    f_owner;  //擁有者通過信號量進行異步I/O傳輸
855        const struct cred    *f_cred;
856        struct file_ra_state    f_ra;
857    
858        u64            f_version;
859    #ifdef CONFIG_SECURITY
860        void            *f_security;  //安全模塊
861    #endif
862        /* needed for tty driver, and maybe others */
863        void            *private_data;  //tty 設備驅動的鈎子
864    
865    #ifdef CONFIG_EPOLL
866        /* Used by fs/eventpoll.c to link all the hooks to this file */
867        struct list_head    f_ep_links;  //事件池鎖
868        struct list_head    f_tfile_llink;
869    #endif /* #ifdef CONFIG_EPOLL */
870        struct address_space    *f_mapping;  //頁緩存映射
871    } __attribute__((aligned(4)));    /* lest something weird decides that 2 is OK */
  • 進程通過文件描述符來訪問文件
  • LInux用一個file文件對象來保存打開文件的位置,這個對象稱為打開的文件描述符
  • file結構主要保存了文件位置,還把指向文件索引節點的指針也放在其中
  • file結構形成一個雙鏈表,稱為系統打開文件表

 6.2 struct file_operations

6.3  struct files_struct

 

  • 文件描述符用來描述打開的文件
  • 每個進程用一個files_struct結構來記錄文件描述符的使用情況
  • 這個files_stuct結構稱為用戶打開文件表,它是進程的私有數據

 

圖 用戶打開文件表

6.4 struct fs_struct

8    struct fs_struct {
9        int users;
10        spinlock_t lock;
11        seqcount_t seq;
12        int umask;  //用於為新創建的文件設置初始文件許可權限
13        int in_exec;
14        struct path root, pwd;
15    };
  • 描述進程與文件系統的關系

 7. 主要數據結構之間的關系

圖 主要數據結構之間的關系

  • 超級塊是對一個文件系統的描述
  • 索引節點是對一個文件物理屬性的描述
  • 目錄項是對一個文件邏輯屬性的描述
  • 一個進程所處的位置由fs_struct描述
  • 一個進程(或用戶)打開的文件由files_struct描述
  • 整個系統所打開的文件由 file結構來描述

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM