Linux 万物皆文件—VFS文件系统

linux 里面当我们执行 ls -li 命令 的时候会发现,很多文件类型。例如:

- 普通文件

d 目录文件

s socket 文件

b 块设备文件 比如说磁盘

l  连接文件

p 管道文件 

他们虽然类型不同,但是linux 对其提供的却是同一套操作接口。这套接口就是VFS(Virtual File System 简称VFS).

VFS  它是 Linux 内核中的一个软件层,用于给用户空间的程序提供文件系统接口;同时,它也提供了内核中的一个 抽象功能,允许不同的文件系统共存。系统中所有的文件系统不但依赖 VFS 共存,而且也依靠 VFS 协同工作。

image.png

                                linux 文件系统架构图

通过这张图可以看出linux支持各种文件系统

第一类是基于磁盘的文件系统,也就是把数据直接存储在计算机本地挂载的磁盘中。常见的 Ext4、XFS、OverlayFS 等,都是这类文件系统。

第二类是基于内存的文件系统,这类文件系统,不需要任何磁盘分配存储空间,但会占用内存。我们经常用到的 /proc 文件系统,其实就是一种最常见的虚拟文件系统。此外,/sys 文件系统也属于这一类,主要向用户空间导出层次化的内核对象。

第三类是网络文件系统,也就是用来访问其他计算机数据的文件系统,比如 NFS、SMB、iSCSI 等。

为了方便管理,Linux文件系统为每个文件都分配了两个数据结构,索引节点,和目录项。

索引节点:用于存储文件的元数据的一个数据结构。文件的元数据,也就是文件的相关信息,和文件本身是两个不同 的概念。它包含的是诸如文件的大小、拥有者、创建时间、磁盘位置,文件权限等和文件相关的信息。索引节点跟文件一一对应,持久化在磁盘里面。索引节点同样占磁盘空间。

索引节点是每个文件的唯一标识。通过ll -i 可以看到第一列就是。

目录项:directory dentry 目录项,简称为 dentry,用来记录文件的名字、索引节点指针以及与其他目录项的关联关系。多个关联的目录项,就构成了文件系统的目录结构。不过,不同于索引节点,目录项是由内核维护的一个内存数据结构,所以通常也被叫做目录项缓存。是不是很难理解? 嘎嘎 那就说的简单点:

在一个文件路径中,路径中的每一部分都被称为目录项;如路径/home/source/helloworld.c中,目录 /, home, source和文件 helloworld.c都是一个目录项。VFS在查找的时候,根据一层一层的目录项找到对应的每个目录项的inode,那么沿着目录项进行操作就可以找到最终的文件。

换句话说,索引节点是每个文件的唯一标志,而目录项维护的正是文件系统的树状结构。目录项和索引节点的关系是多对一,你可以简单理解为,一个文件可以有多个别名。举个例子,通过硬链接为文件创建的别名,就会对应不同的目录项,不过这些目录项本质上还是链接同一个文件,所以,它们的索引节点相同。

超级块 用于存储文件系统的控制信息的数据结构。描述文件系统的状态、文件系统类型、大小、区块数、索引节点数等,存放于磁盘的特定扇区中。

超级块 存储一个已安装的文件系统的控制信息,代表一个已安装的文件系统;每次一个实际的文件系统被安装时, 内核会从磁盘的特定位置读取一些控制信息来填充内存中的超级块对象。一个安装实例和一个超级块对象一一对应

索引节点和目录项纪录了文件的元数据,以及文件间的目录关系,那么具体来说,文件数据到底是怎么存储的呢?是不是直接写到磁盘中就好了呢?

实际上,磁盘读写的最小单位是扇区,然而扇区只有 512B 大小,如果每次都读写这么小的单位,效率一定很低。所以,文件系统又把连续的扇区组成了逻辑块,然后每次都以逻辑块为最小单元,来管理数据。常见的逻辑块大小为 4KB,也就是由连续的 8 个扇区组成。

image.png

磁盘在执行文件系统格式化时,会被分成三个存储区域,超级块、索引节点区和数据块区。其中,

超级块,存储整个文件系统的状态。

索引节点区,用来存储索引节点。

数据块区,则用来存储文件数据。也就是逻辑块所在的地方

那一个进程打开文件的时候流程是怎么样的呢?

进程通过task_struct(每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,Linux内核的进程控制块是task_struct结构体.)

中的一个域files,files_struct(文件结构体)来了解它当前所打开的文件对象;

而我们通常所说的文件描述符(fd)其实是进程打开的文件对象数组的索引值。

文件对象通过域f_dentry找到它对应的dentry对象,再由dentry对象的域d_inode找到它对应的索引结点,这样就建立了文件对象与实际的物理文件的关联。

最后,还有一点很重要的是, 文件对象所对应的文件操作函数列表是通过索引结点的域i_fop得到的.

总结: 1 linux把各种设备也称之为文件

     2 为了管理不同文件系统,linux抽象出一个VFS

     3 文件系统是特殊的数据分层存储结构,它包含文件、目录和相关的控制信息

     4 为了描述这个结构,引入了目录项,索引节点,超级块

     5 超级块可以理解为一个已安装文件系统(例如EXT4,XFS)

     6 索引节点存储一个实际的物理文件的大小,权限,创建时间,属主等信息

     7 目录项 存储在内存里,用以保存文件系统的目录结构,同时还可以用以保存文件名,索引节点指针。

     8 逻辑块 为了提高读写效率,把8个相邻的扇区组合成一个4K的逻辑块。

     9 进程通过打开的文件对象,找到目录项,然后通过里面的索引节点指针找到索引节点,这样就能找到物理文件了。

     

 

https://blog.csdn.net/heikefangxian23/article/details/51579971  这篇很屌,建议阅读。从头读到尾,代码看不懂没关系 看懂图就行了。

https://blog.csdn.net/kickxxx/article/details/9468761 理解linux虚拟文件系统VFS - 概述

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注