在文件系统方面,Linux® 可以算得上操作系统中的 “瑞士军刀”。Linux 支持许多种文件系统,从日志型文件系统到集群文件系统和加密文件系统。对于使用标准的和比较奇特的文件系统以及开发文件系统来说,Linux 是极好的平台。本文讨论 Linux 内核中的虚拟文件系统(VFS,有时候称为虚拟文件系统交换器),然后介绍将文件系统连接在一起的主要结构。
Linux 文件系统体系结构是一个对复杂系统进行抽象化的有趣例子。通过使用一组通用的 API 函数,Linux 可以在许多种存储设备上支持许多种文件系统。例如,read
函数调用可以从指定的文件描述符读取一定数量的字节。read
函数不了解文件系统的类型,比如 ext3 或 NFS。它也不了解文件系统所在的存储媒体,比如 AT Attachment Packet Interface(ATAPI)磁盘、Serial-Attached SCSI(SAS)磁盘或 Serial Advanced Technology Attachment(SATA)磁盘。但是,当通过调用 read
函数读取一个文件时,数据会正常返回。本文讲解这个机制的实现方法并介绍 Linux 文件系统层的主要结构。
首先回答最常见的问题,“什么是文件系统”。文件系统是对一个存储设备上的数据和元数据进行组织的机制。由于定义如此宽泛,支持它的代码会很有意思。正如前 面提到的,有许多种文件系统和媒体。由于存在这么多类型,可以预料到 Linux 文件系统接口实现为分层的体系结构,从而将用户接口层、文件系统实现和操作存储设备的驱动程序分隔开。
|
在 Linux 中将一个文件系统与一个存储设备关联起来的过程称为挂装(mount)。使用 mount
命令将一个文件系统附着到当前文件系统层次结构中(根)。在执行挂装时,要提供文件系统类型、文件系统和一个挂装点。
为了说明 Linux 文件系统层的功能(以及挂装的方法),我们在当前文件系统的一个文件中创建一个文件系统。实现的方法是,首先用 dd
命令创建一个指定大小的文件(使用 /dev/zero 作为源进行文件复制)—— 换句话说,一个用零进行初始化的文件,见清单 1。
|
现在有了一个 10MB 的 file.img 文件。使用 losetup
命令将一个循环设备与这个文件关联起来,让它看起来像一个块设备,而不是文件系统中的常规文件:
$ losetup /dev/loop0 file.img |
这个文件现在作为一个块设备出现(由 /dev/loop0 表示)。然后用 mke2fs
在这个设备上创建一个文件系统。这个命令创建一个指定大小的新的 ext2 文件系统,见清单 2。
清单 2. 用循环设备创建 ext2 文件系统
|
使用 mount
命令将循环设备(/dev/loop0
)所表示的 file.img 文件挂装到挂装点 /mnt/point1。注意,文件系统类型指定为 ext2
。挂装之后,就可以将这个挂装点当作一个新的文件系统,比如使用 ls
命令,见清单 3。
清单 3. 创建挂装点并通过循环设备挂装文件系统
|
如清单 4 所示,还可以继续这个过程:在刚才挂装的文件系统中创建一个新文件,将它与一个循环设备关联起来,再在上面创建另一个文件系统。
清单 4. 在循环文件系统中创建一个新的循环文件系统
|
通过这个简单的演示很容易体会到 Linux 文件系统(和循环设备)是多么强大。可以按照相同的方法在文件上用循环设备创建加密的文件系统。可以在需要时使用循环设备临时挂装文件,这有助于保护数据。