Mac OS X文件系统的来龙去脉(上)
openkk 12年前
<div id="news_body"> <p> 文 / 王越</p> <p> <strong>HFS+ 和 UFS 文件系统同时被引入早期的 Mac OS X,随着若干年的发展,HFS+ 提供的功能已超越 UFS,使其在 Mac OS X 10.5 之后成为成为唯一正式的 Mac OS X 系统,但因为其背负许多的历史包袱,为考虑兼容性,这些陈旧的设计并不能被推翻重来,所以苹果开始秘密研发下一代的文件系统。</strong></p> <p style="text-align:center;"><img title="著名 BSD 开发者 Marshall Kirk McKusick" alt="Mac OS X文件系统的来龙去脉(上)" src="https://simg.open-open.com/show/e521556f6f9915e3c06b05af3a166bc1.jpg" width="277" height="387" /></p> <p style="text-align:center;">著名 BSD 开发者 Marshall Kirk McKusick</p> <p> <strong>UFS:经典的 Unix 文件系统</strong></p> <p> 在 Unix 系统刚诞生的远古时期,文件系统被简单地称为 FS。FS 只包括启动块、超级块(处于硬盘分区开头用来保存文件系统信息)、inodes(索引节点)及数据。FS 文件系统在 Unix 系统刚诞生时还能满足新老客户的需求,但随着科学技术的进步,FS 已不能符合现代文件系统的需求,且会导致抖动等一系列问题。当时还是加州大学伯克利分校研究生,后成为著名 BSD 开发者 Marshall Kirk McKusick 在 BSD 4.1b 上承接传统的 FS 文件系统实现了 FFS(<a href="/misc/goto?guid=4958522366511408719" target="_blank">Fast File System</a>), 妥善地解决了这一难题,把先前整块的磁盘文件系统分为小块,每块包含自已的索引节点和数据,因而增加了文件的局部性,减少了寻道时间。由于 Marshall Kirk McKusick 的 FFS 文件系统很好很强大,所以立即被各大 Unix 系统所使用。SunOS/Solaris、System V Release 4、HP-UX 及 Tru64 UNIX 都使用它,也成为当今各 BSD 分支(FreeBSD、OpenBSD、NetBSD 及 DragonFlyBSD)的标准文件系统。每个不同的系统,无论开源与否,又会在 FFS 文件系统上增加各种扩展,这些扩展往往不互相兼容,但神奇的是,大家又都使用和原版同样的块大小和数据块宽度。因此在很大程度上,这些山寨版 FFS 文件系统又相互兼容,至少在一个操作系统上能对另一操作系统的文件系统执行只读操作。因此,FFS 事实上已经成为 Unix 系统的标准文件系统,故它有了一个更广泛的称谓——UFS(<a href="/misc/goto?guid=4958522366603770147" target="_blank">Unix File System,即 Unix 文件系统</a>)。</p> <p> UFS 在后来的若干年又取得了长足的发展。Sun 公司在 Solaris 7 系统中,给 UFS 提供了简单的日志功能。日志文件系统指在档案系统发生变化时,先把相关的信息写入一个被称为日志的区域,然后再把变化写入主文件系统的文件系统。在文件系 统发生故障(如内核崩溃或突然停电)时,日志文件系统更容易保持一致性,并且可以较快恢复。Marshall Kirk McKusick 又实现了 BSD 一度引以为豪的 <a href="/misc/goto?guid=4958522366694728458" target="_blank">Soft Update</a> 功能,来保证计算机掉电或系统崩溃时,通过使元数据按依赖顺序更新来确保磁盘上总的文件系统保持一致的实现机制。Soft Update 的目标和日志类似,但实现代价比日志轻量许多。不过这项功能有所代价,主要是需要引入一个后台 FSCK 检查。</p> <p> 2009年,Jeff Roberson 正式发表了对 UFS 的一项改进,为 <a href="/misc/goto?guid=4958522366786286929" target="_blank">Soft Update 加入了日志功能</a>,并消除了对 FSCK 的依赖,这项改进最终集成进了 FreeBSD 9 中。<a href="/misc/goto?guid=4958522366902509013" target="_blank">TrustedBSD 项目</a>又为 BSD 分支的文件系统设计了 ACL 访问控制表功能(<a href="/misc/goto?guid=4958522367041568544" target="_blank">Access Control Lists</a>)。 先前,Unix 文件系统的访问控制是非常简单的,其权限管理分为三个不同的类别:用户、同组用户以及其他用户,对每个类别,Unix 文件系统提供读、写、执行三种权限的管理。这样的许可管理过于粗糙,无法指定某一用户访问的权限,也无法指定更为细致的权限内容(例如准许对一文件实行删 除操作)。为解决这个问题,访问控制表被增加到文件系统中,使用以存取控制矩阵为基础的存取控制方法。存取控制串列描述每一个文件对象各自的存取控制,并 记录可对此物件进行存取的所有主体对对象的权限。总之,UFS 与时俱进,不断增加新的功能。</p> <p> <strong>HFS+:更现代的 HFS</strong></p> <p> 作为 Mac OS X 的老祖宗 NeXTSTEP,因为基于 BSD,所以自然也使用 UFS。而老版的 Mac OS 则使用一个叫做 <a href="/misc/goto?guid=4958522367172067563" target="_blank">HFS</a> 的文件系统。HFS 是一个比较古老且不思进取的文件系统,因此,在 20 世纪 90 年代末已不能满足当时的需要。在《<a href="/misc/goto?guid=4958522367300953391" target="_blank">Mac OS X 背后的故事(一)</a>》 中我们提到,为了实现 Mac OS 的现代化,Copland 项目被提出。Copland 项目的子项目 Sequoia 旨在 HFS 的基础上,加入现代文件系统所必需的新功能,如大文件支持、Unicode 文件名支持、长文件名支持、32位文件映射表支持等。Sequoia 项目即成为后来熟知的 HFS+,由 Don Brady 领导,这个团队先花了 6 个月时间把 HFS 项目原本的 Mac 使用的 68K 处理器汇编码改写成C代码,然后逐渐<a href="/misc/goto?guid=4958522367421261887" target="_blank">加入新功能</a>。</p> <p> 后来由于 Copland 被力挽狂澜的 Ellen Hancock 给废了,所以一些有用的更新,如 HFS+ 即被集成到 Mac OS 8.1 中。在 Mac OS X 诞生初期,HFS+ 和 UFS 文件系统同时被引入早期的 Mac OS X 中。不过由于 HFS+ 根植 Mac OS,缺乏 Unix 文件系统所必需的功能,如符号链接、硬链接及其他各种 POSIX 兼容性,所以 HFS+ 开发组又花了一些工夫在不影响和 Mac OS 兼容性的情况下引入了这些功能。由于 HFS+ 是对 HFS 的扩展,故 HFS+ 支持 Mac OS 至 Mac OS X 的平滑过渡,所以 Mac OS X 一直默认使用 HFS+。但当时的 UFS 提供比 HFS+ 更先进的功能,因此 Mac OS X 10.0 至 10.4,也都支持把系统安装在 UFS 系统上。</p> <p> Mac OS X 10.0 发布后,苹果不遗余力地对 HFS+ 进行大规模的扩展和维护,增加了很多 UFS 独有的功能。这些新功能使得文件系统更加安全稳定可靠。例如 Mac OS X 10.2.2 中,HFS+ 支持日志。日志功能在 Mac OS X 10.2 服务器版中可以简单地设定,但在普通桌面版中需要使用命令行进行操作。在 Mac OS X 10.3 中,带日志功能的 HFS+(被称为 HFSJ,即 HFS+ volume with journal)成为默认设置。Mac OS X 10.3 亦增加名件名、目录名区分大小写及 Unicode 3.2 的支持。Mac OS X 10.4 中,HFS+ 更是增加了 ACL 访问控制表功能,提供更复杂的对传统 Unix 文件系统权限的扩展。</p> <p> 文件系统除了让用户供稳定地存放文件这一目标以外,还是各项操作系统功能的基础。Mac OS X 每个大发行版都要增加数百项新功能,许多新功能严重依赖于文件系统的实现。Mac OS X 10.3 提供了 <a href="/misc/goto?guid=4958522367542011945" target="_blank">FileVault 来加密用户文件</a>,因此用户主目录被保存在一个 HFS+ 文件系统加密镜像中。Mac OS X 10.4 提供了<a href="/misc/goto?guid=4958522367640141985" target="_blank">系统内置的 Spotlight 桌面搜寻搜索功能</a>,能让用户对整个磁盘系统进行快速搜寻、随打即显。这项功能要求文件系统提供任意长度文件元数据(metadata)的支持。<a href="/misc/goto?guid=4958522367749175195" target="_blank">Mac OS X 10.4 转向了对 Intel 处理器的支持</a>,因此苹果发布了一个测试版本的 BootCamp 来让用户安装 Mac OS X、Windows 双系统,并在 Mac OS X 10.5 正式集成进系统。</p> <p> 哪怕在 Mac OS X 系统运行,BootCamp 也可以在时调整系统主分区的大小,来空出磁盘空间给 Windows,因此,HFS+ 又需要支持动态分区大小调整。在 Mac OS X 10.5 中集成了 <a href="/misc/goto?guid=4958522367862569561" target="_blank">Time Machine</a>, 它是苹果公司所推出备份的工具程序,于 2006 年 8 月 7 日在苹果计算机全球研发者大会(WWDC)中首次公开,成为当天观众欢呼声最高的功能。Time Machine 对于修改过的文件会在备份盘上保存一个新拷贝,而对于不变的内容,仅在备份盘上存一个指向先前文件的硬链接。因此每一次快照只保存改动的文件,而别的文件 只保存占用空间很少的硬链接。但 Unix 一般只支持文件的硬链接而不支持目录的硬链接。因此 HFS+ 在这点上走得比 Unix 文件系统更远,提供了对于目录的硬链接支持。在 Mac OS X 10.6 中,HFS+ 甚至支持文件系统压缩,使得安装后占用比 Mac OS X 10.5 少得多的空间。Mac OS X 10.7 提出了 <a href="/misc/goto?guid=4958522367952946878" target="_blank">FileVault2</a>, 能加密整个磁盘而不是一个用户目录。这些功能我们在为读者介绍每个发行版时亦会提到,但总之读者看到,HFS+ 的功能随着 Mac OS X 的商业需求不断被扩展。“我在做了这么多工作后回想才发现,我们为 HFS+ 增加了那么多新功能,”苹果前文件系统开发者 Don Brady 如是说。</p> <p> 由于 HFS+ 经过后来若干年的发展,提供的功能已不逊于 UFS,甚至更多更好,故至 Mac OS X 10.5 砍掉了安装至 UFS 的支持。HFS+ 成为唯一正式的 Mac OS X 系统。</p> <p> <strong>HFS+ 并不完美</strong></p> <p> HFS+ 自发布以来,几乎每个发行版都有令人欣喜的改动。它也逐渐成为一个非常完善的文件系统。但 HFS+ 立足于 HFS 设计,HFS 已有 27 年的历史,HFS+ 亦有 14 年历史。这个文件系统有大多的历史包袱,为考虑兼容性,这些陈旧的设计并不能被推翻重来。</p> <p> HFS+ 基于B-树实现,当查找B-树中未使用的节点时,HFS+ 只能每次处理 16 位,原因是老 Mac 使用的 Motorola 的 68K 芯片原生支持 16 位的数据操作。但不管是 PowerPC 还是 Intel,寄存器都支持 256 位宽的寄存器。</p> <p> HFS+ 的元数据(metadata)都以大字节序保存,原因是 Motorola 的 68k 和后来 Mac 使用的 PowerPC 都使用大字节序。但经过 Intel 迁移后,当今的 Mac 都使用 Intel 芯片,而 Intel 芯片是使用小字节序的。因此每当数据读取或存入时,还要经过小字节序和大字节序的转换。远古时期磁盘很慢,计算机处理器的速度也很低,因此进行一次磁盘操 作会占用较多的时间,<a href="/misc/goto?guid=4958522368047852310" target="_blank">HFS+ 的时间分辨率为一秒</a>,但当今的磁盘、处理器处理一次文件系统操作的时间远小于一秒,因此所有主流磁盘文件系统的时间分辨率都是一至数百纳秒级别的。</p> <p> HFS+ 的元数据有全局锁,同一时间只有一个进程可以访问更新文件系统。在单核处理器连手机平板都较少见到的当今,这种设计显得很幼稚。</p> <p> HFS+ 亦没有稀疏文件的支持。例如我们在 SQL 中建立了一个数据库,SQL 分配了 10GB 的文件给这个数据库,并且在文件头和文件尾写上一些字节的数据。而由于我们还没有给这个数据库添加新的数据,所以这 10GB 的文件除了头尾外其他字节都为0。现代的文件系统基本都支持稀疏文件,也就是说,当处理这个数据库操作时,事实上往磁盘写入的数据只有那文件头和文件尾的 若干字节。而 HFS+ 则需要把那些 0 也写上,因此会完整写入 10GB 的数据,耗费长得多的时间。</p> <p> 此外,HFS+ 不具备元数据校验功能、快照功能、写入时复制功能、<a href="/misc/goto?guid=4958522368127216535" target="_blank">就地执行功能</a>、<a href="/misc/goto?guid=4958522368219627740" target="_blank">逻辑卷管理功能</a>等很多现代磁盘系统所具备的功能,也<a href="/misc/goto?guid=4958522368295495110" target="_blank">不能动态调整文件块大小</a>。这些功能的加入并不容易。</p> <p> 其中最要命的是,HFS+ 不像一些先进的文件系统,支持写入时复制事务模型,也没有快照和克隆。这使得用户数据时时处于风险之中。例如由于因为断电、内核崩溃等原因,文件系统上写 到一半的数据,小则导致个别文件损坏,大则导致整个文件系统崩溃。在生产领域,这样不可靠的文件系统,很有可能带来致命的灾难。</p> <p> 正是由于上述这些原因,连我们介绍过的短视的 Linus Torvalds 都认为 HFS+ 是个垃圾文件系统。苹果自然受不了这种侮辱,因此,干掉 HFS+ 势在必行。用什么取代 HFS+ 呢?苹果开始秘密研发下一代的文件系统。</p> <p> <strong>作者王越,美国宾夕法尼亚大学计算机系研究生,中国著名 TeX 开发者,非著名 OpenFOAM 开发者。</strong></p> <div id="come_from"> 来自: <a id="link_source2" href="/misc/goto?guid=4958522368414832490" target="_blank">www.programmer.com.cn</a> </div> </div>