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结构来描述

转载于:https://www.cnblogs.com/smartjourneys/p/7260911.html

Linux文件系统2---VFS的四个主要对象相关推荐

  1. Linux文件系统以及VFS

    Linux文件系统以及VFS 1. 什么是文件系统? 2. 文件系统(文件管理系统的方法)的种类有哪些? 3. 什么是分区? 4. 什么是文件系统目录结构? 5. 什么虚拟文件系统Virtual Fi ...

  2. Linux 文件系统(VFS、EXT、proc)

    主要参考了<深入linux内核>和<Linux内核深度解析>,另外简单浅析了一下相关内容 文章目录 通用文件模型及VfS文件结构 基础知识 文件系统种类 常见的文件系统 VFS ...

  3. 深入理解Linux文件系统之VFS

    1. VFS介绍 "一切皆文件",文件系统是linux系统的基础,Linux内核通过虚拟文件系统(Virtual File System, VFS)管理文件系统 ,VFS为所有的文 ...

  4. linux文件系统基础--VFS中的file、dentry和inode--讲得非常透的一篇文章

    毕业以来,我花了很多时间阅读内核的代码,深入Linux内核架构,深入理解Linux内核,Robert Love的Linux内核设计与实现,Linux的虚拟文件系统对应章节,也读了很多遍,每一次读,都有 ...

  5. linux文件系统与磁盘(四)parted分区工具

    前言 在使用fdisk进行分区时,我们会发现,fdisk具有一定的局限性.因为fdisk分区仅仅有3-4个主分区.这些主分区是有上限的,单个分区一般不超过2TB.而当我们的磁盘空间较大时,例如10TB ...

  6. Linux 文件系统原理 / 虚拟文件系统VFS

    Linux 文件系统原理 / 虚拟文件系统VFS 虚拟文件系统 VFS VFS 定义 VFS 的对象演绎 超级块 super_block 索引节点 inode 目录项 dentry 文件 file 文 ...

  7. Linux 文件系统的目录结构

    1. / 文件系统的入口,最高一级目录: 2. /bin 基础系统所需要的命令位于此目录,是最小系统所需要的命令,如:ls, cp, mkdir等. 这个目录中的文件都是可执行的,一般的用户都可以使用 ...

  8. linux 文件系统 vfs,linux虚拟文件系统vfs

    <操作系统>课程设计报告课程设计题目:操作系统课程设计 设计时间:2016/1/10一. 课程设计目的与要求需要完成的内容:(1) 安装虚拟机:Vmware.Vmware palyer ( ...

  9. 解析 Linux 中的 VFS 文件系统机制

    简介: 本文阐述 Linux 中的文件系统部分,源代码来自基于 IA32 的 2.4.20 内核.总体上说 Linux 下的文件系统主要可分为三大块:一是上层的文件系统的系统调用,二是虚拟文件系统 V ...

最新文章

  1. 一阶和二阶微分方程的物理意义???
  2. anaconda pip install torch报错,安装失败
  3. VMware View 5.2 安装实施七 安装Web Client
  4. 大数据让人们得到更加细致和人性化的服务
  5. 学计算机的管理医生,计算机科学与技术系医学生管理工作体会.pdf
  6. java 延迟初始化_Java并发编程——延迟初始化占位类模式
  7. python 插补数据_python 2020中缺少数据插补技术的快速指南
  8. [快速入门]Spring Boot+springfox-swagger2 之RESTful API自动生成和测试
  9. Oracle常用数据库操作SQL
  10. 百度地图订单分布php,php与百度地图API实现注册用户分布图
  11. 【正点原子STM32连载】 第三十三章 光敏传感器实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1
  12. 中国五千年统一与分裂
  13. PhotoShop 各历史版本
  14. 美女照相怎么摆pose
  15. 行癫:只有合作伙伴和客户成功,才是阿里云的成功
  16. 一般椭圆方程表示的椭圆的绘制
  17. 罗克韦尔自动化和PTC为由PTC支持的FactoryTalk InnovationSuite™添加行业首创的增强功能,用于简化和加速数字化转型
  18. mysql innodb 数据打捞(二)innodb 页面打捞编程
  19. 网易企业邮箱技术剖析
  20. 云计算基础服务(四) http协议--虚拟主机

热门文章

  1. 解决:请购买WinRAR许可,您注册还剩下40天(WinRAR老是弹出烦人的对话框)
  2. Apache POI和EasyExcel 第七集:EasyExcel的基本操作,读取和写入Excel,一行足矣
  3. linux系统文件保存后恢复,linux系统文件误删恢复
  4. js轮询导致服务器瘫痪_演进:Tengine 从 Web 代理服务器 到 分布式推送服务器
  5. 简述用决策表设计测试用例的步骤_决策表快速入门
  6. pycharm设置回退功能
  7. opencv中xml/yml文件操作类
  8. 调试反馈的一种实时反馈方法
  9. MFC消息响应函数OnPaint
  10. vue在created调用点击方法_vue中created、mounted等方法整理