〇、开始之前
这篇文章主要介绍文件系统,内容源于我目前看过的操作系统相关书籍,参考资料会在文章的末尾列出。
介绍文件系统的顺序是自顶向下,首先从用户角度说明了一些文件系统相关概念,然后介绍了一个文件系统内部的原理。至于Linux内部是如何支持一个文件系统的原理,我会放在下篇文章之中。
限于我的知识水平,文中肯定会出现描述有误的地方,欢迎大家指正~
下面我们就开始吧!
一、从用户角度看待文件系统
在计算机操作系统中,文件系统的任务是控制如何存储和检索数据,并且为用户提供一个易于使用的接口。我们把数据称之为“文件”并且为数据起了一个名字叫做“文件名”,用于管理数据及其名称的这组软件我们称之为文件系统,文件系统是操作系统的一部分。
从我们用户的角度来看,文件系统实现了一个key-value存储,key是文件路径,vlaue是数据,使得我们可以方便的使用文件名检索文件,而不必考虑具体的底层细节。
下面是我的一个文件夹a
打开文件管理器,可以看到文件和目录是按照一层一层的关系被展示的,这种结构可以用树表示。如下图就表示了文件夹a中的结构。文件夹a中有两个文件夹b1和b2,还有一个文件file1。
文件夹中包含了子文件夹或者文件,这样就形成了一个树形的结构。不过也有一些特殊情况,例如有个团队在协同工作,他们会共享一些信息,两个人有着不同的家目录,但是可以共享同一份文件。上面的file2和file2_share就代表被共享的文件。
还可以用tree命令输出一个文件夹a的结构
二、从系统角度看待文件系统原理
文件最终是被存储在磁盘之中,所以我们看到的文件系统其实是对磁盘这样一种设备的高层次抽象。
1. 第一层抽象:划分为块序列数组
计算机读取磁盘时按照一个基本单位“块”来读取,为磁盘的每一个基本单元(盘块)分配一个序号,然后把磁盘看作一个线性的结构。
其实这个操作和对内存分配地址序号的操作是一样的,使用一个地址表示一块空间。
2. 第二层抽象:建立文件系统结构
2.1 元数据metadata
借用维基百科的解释:metadata is data about data,数据的数据被称作元数据。例如我有一个文件A(数据),文件A的拥有者,读写权限,数据具体的存储位置等等就被称为元数据。在类Linux和Unix文件系统的世界中,数据和元数据是被分开存放的,并且在多个层次中存在这样的关系。
2.2 将块序列数组划分为三个区域
- 超级块superblock
超级块记录了关于文件系统本身的关键信息(metadata of metadata),包括文件系统的类型,大小,状态以及inode的结构(metadata)。由于超级块非常的重要,因此在文件系统中超级块存在着一定的冗余。
- i-节点区i-node
i代表index,i-node也叫索引节点。一个i-node存储一个文件的元数据,i-node实际上存储了关于所有权(用户、组),访问权限(可读可写可执行),数据的存储位置等等元数据,所以i-node就是一个文件的化身,一个文件对应一个i-node。
值得注意的是:i-node中并不存储文件名这一信息,关于这一点原因将在后面解释。
还有很重要的一点是所有的i-node组成一个线性结构,并且通过下标来标识,下标也叫做i-node号,这个和磁盘盘块号不一样,inode是建立在盘块上的。
- 数据区data
最后一个部分是数据区,文件的内容(数据)就保存在这个区域。一个磁盘上的块大小是固定的,如果一个文件的大小大于一个磁盘块的话,数据会分布在多个磁盘块之中,文件系统(i-node)负责追踪这些数据块。
3. i-node如何追踪文件分布的盘块
Linux和Unix将文件的数据和元数据分开存放,具体来讲inode存储元数据,数据区存储数据。在i结点中不必存储真正的数据,但是需要存储数据被放在了数据区的哪个位置。inode保存着文件在数据区的盘块列表,这也是索引结点名称inode的由来。
4. 目录是什么?
在Linux中,目录本身被当作一个文件对待。因此目录也有一个对应的i-node,而目录存储在数据区的数据其实就是文件名和i-node号的映射列表,目录就像是文件和文件之间的粘合剂。系统内部使用i-node号索引文件,而用户使用文件名索引文件。
每个目录都有两个特殊的文件名”.” 和 “. .”,其中”.” 代表目录文件本身的名字,“. .”代表父目录的名字。
例如a是一个目录,可以使用-i选项打印出文件的i-node号码。第一列是i-node号,第二列是文件名
5. 文件树
通过目录中包含目录的形式,所有的文件就形成了一个树形的结构。用户眼中的文件系统在系统内部的样子如下。
检索文件时通过目录寻找到目标文件的i-node编号,再通过i-node追踪到对应文件数据所在的盘块,读出相应的数据。
6. 文件名本质是什么?
先上图
可以看出其实蓝色的文件名代表了一个指向i-node结点的指针,这个指针在Linux中通常叫做硬链接,这个硬链接的名字就是文件名。这样多个文件名(指针)可以指向同一个文件,实现文件的共享。
可以用ls查看是否入上图所示,这两个文件确实有着相同的i-node号。
三、结束
这就是关于文件系统的基础知识了,如果你觉得还不错的话欢迎关注我的微信公众号「计万鹏是个程序员」。
往期内容:
PenG:图解Linux中的虚拟内存机制和内存映射zhuanlan.zhihu.com参考资料 《Unix/Linux编程实践教程》
《Linux内核设计与实现》