虚拟文件系统 (VFS)
虚拟文件系统 (VFS)
概念
文件系统的种类众多,而操作系统希望 对用户提供一个统一的接口,于是在用户层与文件系统层引入了中间层,这个中间层就称为 虚拟文件系统(Virtual File System,VFS)。
VFS 定义了一组所有文件系统都支持的数据结构和标准接口,这样程序员不需要了解文件系统的工作原理,只需要了解 VFS 提供的统一接口即可。
在 Linux 文件系统中,用户空间、系统调用、虚拟文件系统、缓存、文件系统以及存储之间的关系如下图:
(第二张图来自:https://xiaolizai.blog.csdn.net/article/details/133993884)
文件系统分类 - 按存储位置
Linux 支持的文件系统也不少,根据存储位置的不同,可以把文件系统分为三类:
- 磁盘的文件系统: 它是直接把数据存储在磁盘中,比如
Ext 2/3/4
、XFS
等都是这类文件系统 - 内存的文件系统: 这类文件系统的数据不是存储在硬盘的,而是占用内存空间,我们经常用到的
/proc
和/sys
文件系统都属于这一类,读写这类文件,实际上是读写内核中相关的数据 - 网络的文件系统: 用来访问其他计算机主机数据的文件系统,比如
NFS
、SMB
等等
文件系统首先要先挂载到某个目录才可以正常使用,比如 Linux 系统在启动时,会把文件系统挂载到根目录。
VFS四大struct
参考:https://blog.csdn.net/bandaoyu/article/details/125375996
VFS有四大对象:
- 超级块 super_block
- 索引节点 inode
- 目录项 dentry
- 文件对象 file
(1) 索引节点 inode
文件是由 inode 以及 inode指向的数据块构成,Inode记录了文件的管理信息,数据块记录文件的具体内容。
(2) 目录项 dentry
目录:也是由 inode 以及inode指向的数据块构成 ,但目录的数据块 记录的是该目录下的 子目录/文件的 inode 以及 子目录名/文件名 等信息。
目录项 dentry:目录项是描述文件的逻辑属性(dentry中包含了文件名,文件的inode号等信息。),只存在于内存中,更确切的说是存在于内存的目录项缓存,为了提高查找性能而设计。注意不管是文件夹还是最终的文件,都是属于目录项,所有的目录项在一起构成一颗庞大的目录树。
例如:open一个文件 /home/xxx/yyy.txt,那么 /、home、xxx、yyy.txt 都是一个目录项,VFS在查找的时候,根据一层一层的目录项找到对应的每个目录项的inode,那么沿着目录项进行操作就可以找到最终的文件。
dentry结构是一种含有指向父节点和子节点指针的双向结构,多个这样的双向结构构成一个内存里面的树状结构,也就是文件系统的目录结构在内存中的缓存了。有了这个缓存,我们在访问文件系统时,通常都非常快捷。
注意:目录也是一种文件(所以也存在对应的inode)。打开目录,实际上就是打开目录文件
举个文件的例子:/home/user/Desktop/bilibili.txt ,假设 bilibili.txt和 / 在同一个文件系统,那么,只需要读 /的inode
读到 home 并找到找到 home的inode
并读取,这样步步跳转,最后会读取 bilibili.txt 这文件对应的 inode ,好了,你打开 bilibili.txt 这个文件并读取内容时,VFS 会调用 ext3 的 read()(在5中的安装 ,函数已经向VFS注册过)去读此inode对应的数据块。
(3) 文件对象
文件对象:注意文件对象描述的是进程已经打开的文件。因为一个文件可以被多个进程打开,所以一个文件可以存在多个文件对象。但是由于文件是唯一的,那么inode就是唯一的,目录项也是定的!
进程其实是通过文件描述符来操作文件的,注意每个文件都有一个32位的数字来表示下一个读写的字节位置,这个数字叫做文件位置。一般情况下打开文件后,打开位置都是从0开始,除非一些特殊情况。Linux用file结构体来保存打开的文件的位置,所以file称为打开的文件描述。这个需要好好理解一下!file结构形成一个双链表,称为系统打开文件表。
Superblock, Inode, Dentry 和 File 都属于元数据(Metadata),
Linux系统从ext2开始,是将文件属性和文件内容分开存储,inode 用于存储文件的各属性,block 用来存储文件的内容。inode指向block(至少一个)。
超级块
Super block即为超级块,它是硬盘分区开头,超级块中的数据是卷资源表,有关文件卷的大部分信息都保存在这里。
例如:硬盘分区中每个block的大小、硬盘分区上一共有多少个block group、以及每个block group中有多少个inode。它定义了文件系统的类似、大小、状态,和其他元数据结构的信息(元数据的元数据)。
读linux下文件--->陷入kernel-->VFS系统-->文件系统(例如ext3)-->访问物理硬件;
Superblock, Inode, Dentry 和 File 都属于元数据(Metadata)