《Linux内核设计与实现》笔记——VFS

Posted xcy6666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Linux内核设计与实现》笔记——VFS相关的知识,希望对你有一定的参考价值。

关于VFS有一篇很好的博客http://www.ibm.com/developerworks/cn/linux/l-vfs/
建议先阅读本文为基础,然后继续阅读该文章。

VFS,虚拟文件系统,为用户提供了文件和文件系统相关的接口。
这些接口可以跨越各种文件系统和不同介质执行。
VFS提供了一个通用文件系统模型,该模型囊括了任何文件系统的常用功能集和行为。
这里写图片描述
该模型偏重于Unix风格的文件系统。

数据结构关系

如下图,下图描述了VFS相关数据结构的关系
这里写图片描述

Unix文件系统

Unix使用了4个和文件系统相关的传统概念:文件目录项索引节点安装点(mount point)

文件

简单的面向字节流的抽象

目录项

文件通过目录组织起来,目录中的每一个部分都是一个目录条目, /home/wolfman/butter , / , home, wolfman , butter 都是目录条目,统称为目录项

索引节点

Unix文件系统,将文件的相关信息和文件本身区分开来。文件控制信息,如权限,拥有者,大小,创建时间等”元数据”,被存储在一个单独的数据结构中,该结构被称为索引节点inode

安装点/挂载点

linux中的磁盘文件系统的入口目录,类似于windows中的用来访问不同分区的C:、D:、E:等盘符。[百度百科词条]

文件系统的信息存储在超级块中,集单独文件信息和文件系统信息于一身。
对于FAT,NTFS这种,虽然也可以在Linux上工作,但必须进行封装。比如:一个文件系统不支持索引节点,也必须在内存中装配索引节点结构体,就像它本身包含一样。

VFS对象及数据结构

  • 超级块对象

    • 代表一个具体的已安装文件系统,由super_block结构体表示,定义于<linux/fs.h>
    • 包含操作对象super_operations对象,包括内核针对特定文件系统所能调用的方法,定义于<linux/fs.h>
      • 超级块对象通过alloc_super()函数创建并初始化。在文件系统安装时,文件系统会调用该函数以便从磁盘读取文件系统超级块,并将其信息填充到内存中的超级块对象中
    • 各种文件系统都必须实现超级块对象,该对象用于存储特定文件系统信息,通常对应于存放在磁盘特定扇区的文件系统超级块或系统控制块。
      super_block
      http://lxr.free-electrons.com/source/include/linux/fs.h?v=3.11#L1242
      super_operations
      http://lxr.free-electrons.com/source/include/linux/fs.h?v=3.11#L1604
  • 索引节点对象

    • 代表一个具体文件,包含了内核在操作文件或目录时需要的全部信息,由inode结构体表示,定义于<linux/fs.h>
      • unix风格的文件系统可以直接从磁盘索引节点读入,如果一个文件系统没有索引节点,文件系统需要从磁盘上提取相关信息(没有inode的文件系统通常将文件描述信息作为文件的一部分)
      • 索引节点必须在内存中创建,以便于文件系统使用
    • 包含操作对象inode_operations对象,包括针对特定文件所能调用的方法,定义于<linux/fs.h>
    • 索引节点代表文件系统中的一个文件(但索引节点仅当文件被访问时,才在内存中创建),也可以是设备管道这样的特殊文件
      inode
      http://lxr.free-electrons.com/source/include/linux/fs.h?v=3.11#L523
      inode_operations
      http://lxr.free-electrons.com/source/include/linux/fs.h?v=3.11#L1559
  • 目录项对象
    • 代表一个目录项,是路径的一个组成部分,由dentry结构体表示,定义于<linux/dcache.h>
    • 包含dentry_operations对象,其中包括内核针对特定目录所能调用的方法,定义<linux/dcache.h>
    • VFS把目录当文件对待,路径中的每一个组成部分都由一个索引节点对象表示。为方便查找操作,vfs引入目录项,每个dentry代表路径中的一个特定部分,/bin/vi,这个路径,/,bin,vi(文件)都是目录项对象。
    • 目录项也可包括安装点,/mnt/cdrom/foo,构成元素/,mnt,cdrom,foo都是目录项
    • vfs在执行目录操作时,如果需要会现场创建目录项对象。
    • 目录学没有对应的磁盘数据结构,vfs根据字符串路径名现场创建
    • 目录项缓存在目录项缓存dcache中,以加速查找操作
      dentry
      http://lxr.free-electrons.com/source/include/linux/dcache.h?v=3.11#L106
      dentry_operations
      http://lxr.free-electrons.com/source/include/linux/dcache.h?v=3.11#L148
  • 文件对象
    • 代表由进程打开的文件,由file结构体表示,定义于<linux/fs.h>
    • 包含file_operations对象,其中包括进程针对已经打开的文件所能调用的方法,定义于<linux/fs.h>
    • 多个进程可以同时打开和操作同一个文件,所以同一个文件可能对应多个文件对象。
    • 文件对象仅在进程观点上代表已打开文件,它反过来指向dentry(反过来指向inode),只有目录项才代表打开的实际文件。文件对应的文件对象不是唯一的,但对应的索引节点和目录项对象和文件是唯一的。
      file
      http://lxr.free-electrons.com/source/include/linux/fs.h?v=3.11#L765
      file_operations
      http://lxr.free-electrons.com/source/include/linux/fs.h?v=3.11#L1528
      因为VFS将目录作为一个文件来处理,所以不存在目录对象。

其他相关数据结构

和文件系统相关的数据结构

  • file_system_type
    • 用来描述各种特定文件系统,定义于<linux/fs.h>,如ext3,ext4
    • 每种文件系统,不论是否被安装,都只有一个file_system_type结构体
      kernel 3.11
struct file_system_type {
         const char *name;
         int fs_flags;
#define FS_REQUIRES_DEV         1 
#define FS_BINARY_MOUNTDATA     2
#define FS_HAS_SUBTYPE          4
#define FS_USERNS_MOUNT         8       //Can be mounted by userns root 
#define FS_USERNS_DEV_MOUNT     16 // A userns mount does not imply MNT_NODEV 
#define FS_RENAME_DOES_D_MOVE   32768   /* FS will handle d_move() during rename() internally. */
         struct dentry *(*mount) (struct file_system_type *, int,const char *, void *);
        void (*kill_sb) (struct super_block *);
        struct module *owner;
        struct file_system_type * next;
        struct hlist_head fs_supers;

        struct lock_class_key s_lock_key;
        struct lock_class_key s_umount_key;
        struct lock_class_key s_vfs_rename_key;
        struct lock_class_key s_writers_key[SB_FREEZE_LEVELS];

        struct lock_class_key i_lock_key;
        struct lock_class_key i_mutex_key;
        struct lock_class_key i_mutex_dir_key;
};
  • vfsmont
    • 用来描述一个安装文件系统的实例,定义于<linux/mount.h>
    • 文件系统被实际安装时,一个vfsmount结构在安装点创建,代表文件系统的实例,换句话说,代表安装点。
struct vfsmount {
     struct dentry *mnt_root;/* root of the mounted tree */
     struct super_block *mnt_sb;/* pointer to superblock */
     int mnt_flags;
};

和进程相关的数据结构

file_struct
定义于<linux/fdtable.h> 与单个进程相关的信息都包含在内
fs_struct
定义于<linux/fs_struct.h> 包含文件系统和进程相关信息
namespace
定义于<linux/mnt_namespace.h>
使得每一个进程在系统中看到唯一的安装文件系统,不仅是唯一的根目录,而是唯一的文件系统层次结构

Linux存储栈

这里写图片描述
[ https://www.thomaskrenn.com/en/wiki/Linux_Storage_Stack_Diagram ]

以上是关于《Linux内核设计与实现》笔记——VFS的主要内容,如果未能解决你的问题,请参考以下文章

Linux内核设计与实现高清版pdf免费下载

《Linux内核设计与实现》读书笔记- 内核数据结构

《linux内核设计与实现》读书笔记第十八章

Linux内核设计与实现读书笔记——第三章

《linux内核设计与实现》读书笔记第三章

《Linux内核设计与实现》读书笔记从内核出发