第3章讨论了Linux如何通过文件系统来在存储设备上存储文件和目录。Linux的文件系统为
我们在硬盘中存储的0和1和应用中使用的文件与目录之间搭建起了一座桥梁。

Linux支持多种类型的文件系统管理文件和目录。每种文件系统都在存储设备上实现了虚拟
目录结构,仅特性略有不同。本章将带你逐步了解Linux环境中较常用的文件系统的优点和缺陷。

8.1.1 基本的 Linux 文件系统

Linux最初采用的是一种简单的文件系统,它模仿了Unix文件系统的功能。本节讨论了这种
文件系统的演进过程。

1. ext文件系统

Linux操作系统中引入的最早的文件系统叫作扩展文件系统(extended filesystem,简记为ext)。
它为Linux提供了一个基本的类Unix文件系统:使用虚拟目录来操作硬件设备,在物理设备上按
定长的块来存储数据。

ext文件系统采用名为索引节点的系统来存放虚拟目录中所存储文件的信息。索引节点系统
在每个物理设备中创建一个单独的表(称为索引节点表)来存储这些文件的信息。存储在虚拟目
录中的每一个文件在索引节点表中都有一个条目。ext文件系统名称中的extended部分来自其跟踪
的每个文件的额外数据,包括:

  •  文件名
  •  文件大小
  •  文件的属主
  •  文件的属组
  •  文件的访问权限
  •  指向存有文件数据的每个硬盘块的指针

Linux通过唯一的数值(称作索引节点号)来引用索引节点表中的每个索引节点,这个值是
创建文件时由文件系统分配的。文件系统通过索引节点号而不是文件全名及路径来标识文件。

2. ext2文件系统

最早的ext文件系统有不少限制,比如文件大小不得超过2 GB。在Linux出现后不久,ext文件
系统就升级到了第二代扩展文件系统,叫作ext2。

如你所猜测的,ext2文件系统是ext文件系统基本功能的一个扩展,但保持了同样的结构。ext2
文件系统扩展了索引节点表的格式来保存系统上每个文件的更多信息。

ext2的索引节点表为文件添加了创建时间值、修改时间值和最后访问时间值来帮助系统管理
员追踪文件的访问情况。ext2文件系统还将允许的最大文件大小增加到了2 TB(在ext2的后期版
本中增加到了32 TB),以容纳数据库服务器中常见的大文件。

除了扩展索引节点表外,ext2文件系统还改变了文件在数据块中存储的方式。ext文件系统常
见的问题是在文件写入到物理设备时,存储数据用的块很容易分散在整个设备中(称作碎片化,
fragmentation)。数据块的碎片化会降低文件系统的性能,因为需要更长的时间在存储设备中查找
特定文件的所有块。

保存文件时,ext2文件系统通过按组分配磁盘块来减轻碎片化。通过将数据块分组,文件系
统在读取文件时不需要为了数据块查找整个物理设备。
多年来,ext文件系统一直都是Linux发行版采用的默认文件系统。但它也有一些限制。索
引节点表虽然支持文件系统保存有关文件的更多信息,但会对系统造成致命的问题。文件系统
每次存储或更新文件,它都要用新信息来更新索引节点表。问题在于这种操作并非总是一气呵
成的。

如果计算机系统在存储文件和更新索引节点表之间发生了什么,这二者的内容就不同步了。
ext2文件系统由于容易在系统崩溃或断电时损坏而臭名昭著。即使文件数据正常保存到了物理设
备上,如果索引节点表记录没完成更新的话,ext2文件系统甚至都不知道那个文件存在!

很快开发人员就开始尝试开发不同的Linux文件系统了。

8.1.2 日志文件系统

日志文件系统为Linux系统增加了一层安全性。它不再使用之前先将数据直接写入存储设备
再更新索引节点表的做法,而是先将文件的更改写入到临时文件(称作日志,journal)中。在数
据成功写到存储设备和索引节点表之后,再删除对应的日志条目。

如果系统在数据被写入存储设备之前崩溃或断电了,日志文件系统下次会读取日志文件并处
理上次留下的未写入的数据。

Linux中有3种广泛使用的日志方法,每种的保护等级都不相同,如表8-1所示。
image.png

数据模式日志方法是目前为止最安全的数据保护方法,但同时也是最慢的。所有写到存储设
备上的数据都必须写两次:第一次写入日志,第二次写入真正的存储设备。这样会导致性能很差,
尤其是对要做大量数据写入的系统而言。

这些年来,在Linux上还出现了一些其他日志文件系统。后面几节将会讲述常见的Linux日志
文件系统。

1. ext3文件系统

2001年,ext3文件系统被引入Linux内核中,直到最近都是几乎所有Linux发行版默认的文件
系统。它采用和ext2文件系统相同的索引节点表结构,但给每个存储设备增加了一个日志文件,
以将准备写入存储设备的数据先记入日志。

默认情况下,ext3文件系统用有序模式的日志功能——只将索引节点信息写入日志文件,直
到数据块都被成功写入存储设备才删除。你可以在创建文件系统时用简单的一个命令行选项将
ext3文件系统的日志方法改成数据模式或回写模式。

虽然ext3文件系统为Linux文件系统添加了基本的日志功能,但它仍然缺少一些功能。例如
ext3文件系统无法恢复误删的文件,它没有任何内建的数据压缩功能(虽然有个需单独安装的补
丁支持这个功能),ext3文件系统也不支持加密文件。鉴于这些原因,Linux项目的开发人员选择
再接再厉,继续改进ext3文件系统。

2. ext4文件系统

扩展ext3文件系统功能的结果是ext4文件系统(你可能也猜出来了)。ext4文件系统在2008年
受到Linux内核官方支持,现在已是大多数流行的Linux发行版采用的默认文件系统,比如Ubuntu。

除了支持数据压缩和加密,ext4文件系统还支持一个称作区段(extent)的特性。区段在存储
设备上按块分配空间,但在索引节点表中只保存起始块的位置。由于无需列出所有用来存储文件
中数据的数据块,它可以在索引节点表中节省一些空间。

ext4还引入了块预分配技术(block preallocation)。如果你想在存储设备上给一个你知道要变
大的文件预留空间,ext4文件系统可以为文件分配所有需要用到的块,而不仅仅是那些现在已经
用到的块。ext4文件系统用0填满预留的数据块,不会将它们分配给其他文件。

3. Reiser文件系统

2001年,Hans Reiser为Linux创建了第一个称为ReiserFS的日志文件系统。ReiserFS文件系统
只支持回写日志模式——只把索引节点表数据写到日志文件。ReiserFS文件系统也因此成为Linux
上最快的日志文件系统之一。

有两个有意思的特性被引入了ReiserFS文件系统:一个是你可以在线调整已有文件系统的大
小;另一个是被称作尾部压缩(tailpacking)的技术,该技术能将一个文件的数据填进另一个文
件的数据块中的空白空间。如果你必须为已有文件系统扩容来容纳更多的数据,在线调整文件系
统大小功能非常好用。

4. JFS文件系统

作为可能依然在用的最老的日志文件系统之一,JFS(Journaled File System,日志化文件系
统①)是IBM在1990年为其Unix衍生版AIX开发的。然而直到第2版,它才被移植到Linux环境中。


说明 IBM官方称JFS文件系统的第2版为JFS2,但大多数Linux系统提到它时都只用JFS。


JFS文件系统采用的是有序日志方法,即只在日志中保存索引节点表数据,直到真正的文件
数据被写进存储设备时才删除它。这个方法在ReiserFS的速度和数据模式日志方法的完整性之间
的采取的一种折中。

JFS文件系统采用基于区段的文件分配,即为每个写入存储设备的文件分配一组块。这样可
以减少存储设备上的碎片。

除了用在IBM Linux上外,JFS文件系统并没有流行起来,但你有可能在同Linux打交道的日
子中碰到它。

5. XFS文件系统

XFS日志文件系统是另一种最初用于商业Unix系统而如今走进Linux世界的文件系统。美国
硅图公司(SGI)最初在1994年为其商业化的IRIX Unix系统开发了XFS。2002年,它被发布到了
适用于Linux环境的版本。

XFS文件系统采用回写模式的日志,在提供了高性能的同时也引入了一定的风险,因为实际
数据并未存进日志文件。XFS文件系统还允许在线调整文件系统的大小,这点类似于ReiserFS文
件系统,除了XFS文件系统只能扩大不能缩小。
——————————
① 此处“日志化文件系统”是指Journaled File System这一Journal File System概念的具体实现。为防止读者混淆,后
文中都将用JFS缩写代替。

8.1.3 写时复制文件系统

采用了日志式技术,你就必须在安全性和性能之间做出选择。尽管数据模式日志提供了最高
的安全性,但是会对性能带来影响,因为索引节点和数据都需要被日志化。如果是回写模式日志,
性能倒是可以接受,但安全性就会受到损害。

就文件系统而言,日志式的另一种选择是一种叫作写时复制(copy-on-write,COW)的技术。
COW利用快照兼顾了安全性和性能。如果要修改数据,会使用克隆或可写快照。修改过的数据
并不会直接覆盖当前数据,而是被放入文件系统中的另一个位置上。即便是数据修改已经完成,
之前的旧数据也不会被重写。

COW文件系统已日渐流行,接下来会简要概览其中最流行的两种(Btrf和ZFS)。

1. ZFS文件系统

COW文件系统ZFS是由Sun公司于2005年研发的,用于OpenSolaris操作系统,从2008年起开
始向Linux移植,最终在2012年投入Linux产品的使用。

ZFS是一个稳定的文件系统,与Resier4、Btrfs和ext4势均力敌。它最大的弱项就是没有使用
GPL许可。自2013年发起的OpenZFS项目有可能改变这种局面。但是,在获得GPL许可之前,ZFS
有可能终无法成为Linux默认的文件系统。

2. Btrf文件系统

Btrfs文件系统是COW的新人,也被称为B树文件系统。它是由Oracle公司于2007年开始研发
的。Btrfs在Reiser4的诸多特性的基础上改进了可靠性。另一些开发人员最终也加入了开发过程,
帮助Btrfs快速成为了最流行的文件系统。究其原因,则要归于它的稳定性、易用性以及能够动态
调整已挂载文件系统的大小。OpenSUSE Linux发行版最近将Btrfs作为其默认文件系统。除此之
外,该文件系统也出现在了其他Linux发行版中(如RHEL),不过并不是作为默认文件系统。