我们无时无刻不在使用文件系统,进行开发的时候在使用文件系统,浏览网页的时候在使用文件系统,玩手机的时候也在使用文件系统。
对于非专业人士来说,可能根本不知道文件系统为何物。因为,通常来说,我们在使用文件系统的时候一般不会感知到文件系统的存在。即使对于程序开发人员,很多人对于文件系统也是一知半解。
虽然文件系统经常不被感知,但是文件系统却是非常重要的。在Linux操作系统系统中文件系统是Linux内核的四大子系统之一;而在Windows之前,微软的DOS系统,其全称是DiskOperatingSystem,也就是磁盘管理系统,说白了就是一个文件系统。
刨根问底文件系统
想要更加深入的理解文件系统,首先要弄明白什么是文件系统。业界并没有给文件系统下一个明确的定义,作者翻阅《操作系统概念》和《现代操作系统》等比较著名的操作系统书籍,并没有找到关于文件系统的明确定义。在维基百科发现了对文件系统的如下描述:
In computing, a file system or filesystem (often abbreviated to fs) controls how data is stored and retrieved.
另外一个对文件系统概念进行描述的地方是Definitions,这是一个专业提供各种定义的网站,给出了如下解释:
In computing, a file system is a type of data store which can be used to store, retrieve and update a set of files.
虽然我们没有找到明确的定义,但从前面找到的对文件系统的描述可以知道文件系统是一个控制数据存取的系统。而通常我们所说的文件系统是构建在磁盘(含SSD盘和SD卡等)之上的。因此,我们通常所说的文件系统其实就是一个对磁盘空间进行管理,实现数据存取的系统。
狭义的理解文件系统实现对磁盘、软盘或者光盘等块设备的数据进行存取,而广义来说,文件系统未必需要构建在磁盘之上,它还可以构建在网络或者内存之上。无论构建在那种设备上,最为核心的是实现对数据的存取。
除了实现对数据的存取之外,文件系统更重要的一个功能是文件系统抽象了一个更加容易访问存储空间的接口。这里的接口包括用于程序开发的API接口和普通用户的操作接口。为了便于理解,我们可以将文件系统对磁盘空间的管理用图1表示。
图1 从磁盘到文件系统
对于上图,我们简单的解释一下。最底层是硬件设备,我们这里以硬磁盘为例。磁盘驱动器和操作系统对硬磁盘做了很好的抽象,它们将复杂的硬磁盘抽象为一个连续的线性空间。最后是文件系统,将线性空间进行管理和抽象,呈现给用户一个层级结构。这里的层级结构就是我们平常看到的目录,子目录和文件等元素的集合,如图2所示。
图2 文件系统实例
通过上面这张图可能并不能很清楚的了解文件系统的层级结构。我们给出Linux操作系统中文件系统的一个概图,如图3所示。通过该图可以看出,文件系统中的数据呈现为一个树形结构。各个目录与子目录之间呈层级的结构。
图3 树形结构的文件系统
文件系统的数据管理
文件系统最核心的特性自然是数据管理了。这里的数据管理包括对整个磁盘的数据管理和对文件的数据管理两部分。
对磁盘的管理主要是将磁盘划分为不同的功能区,最为简单的画法就是分为元数据区和数据区。实际文件系统的处理要复杂一些,以Ext2为例,其将磁盘空间划分为等大小的块组,然后再对每个块组进行管理。
图4 Ext2磁盘空间管理
在一个块组中,最基础的信息包含数据位图,inode表位图,inode表和数据区。对于磁盘空间的管理其实就是通过位图来管理的,位图用来标志某块数据是否已经被使用的。当然,不同的文件系统的管理略有不同,但原理大同小异。
另外一个比较重要的地方就是对文件数据的管理了。对于普通用户来说文件就是一个线性的数据空间,好比一个大数组。但是磁盘上可能无法提供这么大的空间。因此文件系统在管理文件的时候是将文件切割为一定大小的逻辑块的。这样,文件系统的做法是将文件的逻辑块与磁盘的物理块建立对应关系。这样,当我们访问文件某个位置的数据的时候就可以在磁盘上找到了。