扩展文件系统 (ext fs)、第二代扩展文件系统 (ext2fs) 和第三代扩展文件系统 (ext3fs) 是由 Rmy Card(Laboratoire MASI--Institut Blaise Pascal,< card@masi.ibp.fr>)、Theodore Ts'o(Massachussets Institute of Technology,< tytso@mit.edu>)和 Stephen Tweedie(University of Edinburgh,< sct@redhat.com>)在 Linux 上设计和实现的。
这是早期 Linux 系统中使用的旧文件系统。
第二代扩展文件系统可能是 Linux 社区中最广泛使用的文件系统。它提供标准的 Unix 文件语义和高级功能。此外,由于内核代码中包含的优化,它非常稳健并提供出色的性能。
由于 Ext2fs 在设计时考虑了演进,因此它包含可用于添加新功能的钩子。有些人正在研究当前文件系统的扩展:符合 Posix 语义的访问控制列表、取消删除和即时文件压缩。
Ext2fs 最初是在 Linux 内核中开发和集成的,现在正积极地移植到其他操作系统。已经在 GNU Hurd 之上实现了一个 Ext2fs 服务器。人们还在 Mach 微内核之上的 LITES 服务器和 VSTa 操作系统中进行 Ext2fs 端口的开发。最后但同样重要的是,Ext2fs 是 Masix 操作系统的重要组成部分,该操作系统目前正由作者之一开发。
第二代扩展文件系统的设计和实现是为了解决第一代扩展文件系统中存在的一些问题。我们的目标是提供一个功能强大的文件系统,它实现 Unix 文件语义并提供高级功能。
当然,我们希望 Ext2fs 具有出色的性能。我们还希望提供一个非常稳健的文件系统,以降低在密集使用中数据丢失的风险。最后但同样重要的是,Ext2fs 必须包含扩展条款,以便用户能够从新功能中受益,而无需重新格式化其文件系统。
Ext2fs 支持标准的 Unix 文件类型:普通文件、目录、设备特殊文件和符号链接。
Ext2fs 能够管理在非常大的分区上创建的文件系统。虽然原始内核代码将最大文件系统大小限制为 2 GB,但 VFS 层最近的工作已将此限制提高到 4 TB。因此,现在可以使用大磁盘,而无需创建许多分区。
Ext2fs 提供长文件名。它使用可变长度目录项。最大文件名大小为 255 个字符。如果需要,此限制可以扩展到 1012。
Ext2fs 为超级用户 (root
) 保留了一些块。通常,保留 5% 的块。这允许管理员轻松地从用户进程填满文件系统的情况中恢复。
除了标准的 Unix 功能外,Ext2fs 还支持一些通常在 Unix 文件系统中不存在的扩展。
文件属性允许用户在对一组文件执行操作时修改内核行为。可以在文件或目录上设置属性。在后一种情况下,在目录中创建的新文件将继承这些属性。
可以在挂载时选择 BSD 或 System V Release 4 语义。挂载选项允许管理员选择文件创建语义。在以 BSD 语义挂载的文件系统上,创建的文件具有与其父目录相同的组 ID。System V 语义稍微复杂一些:如果目录设置了 setgid 位,则新文件继承目录的组 ID,子目录继承组 ID 和 setgid 位;在另一种情况下,文件和子目录以调用进程的主组 ID 创建。
类似 BSD 的同步更新可以在 Ext2fs 中使用。挂载选项允许管理员请求在修改元数据(inode、位图块、间接块和目录块)时将其同步写入磁盘。这对于保持严格的元数据一致性很有用,但这会导致性能不佳。实际上,此功能通常不使用,因为除了与使用元数据同步更新相关的性能损失之外,它还可能导致用户数据损坏,而文件系统检查器不会标记该损坏。
Ext2fs 允许管理员在创建文件系统时选择逻辑块大小。块大小通常可以是 1024、2048 和 4096 字节。使用大块大小可以加快 I/O 速度,因为访问文件所需的 I/O 请求更少,因此磁盘磁头寻道次数也更少。另一方面,大块会浪费更多磁盘空间:平均而言,分配给文件的最后一个块只有一半是满的,因此随着块变大,每个文件的最后一个块中会浪费更多空间。此外,Ext2 文件系统的预分配技术已经获得了较大块大小的大部分优势。
Ext2fs 实现了快速符号链接。快速符号链接不使用文件系统上的任何数据块。目标名称不存储在数据块中,而是存储在 inode 本身中。此策略可以节省一些磁盘空间(无需分配数据块),并加快链接操作(访问此类链接时无需读取数据块)。当然,inode 中可用的空间是有限的,因此并非每个链接都可以实现为快速符号链接。快速符号链接中目标名称的最大大小为 60 个字符。我们计划在不久的将来将此方案扩展到小文件。
Ext2fs 跟踪文件系统状态。内核代码使用超级块中的一个特殊字段来指示文件系统的状态。当文件系统以读/写模式挂载时,其状态设置为“未清理”。当它卸载或以只读模式重新挂载时,其状态将重置为“已清理”。在启动时,文件系统检查器使用此信息来决定是否必须检查文件系统。内核代码还在该字段中记录错误。当内核代码检测到不一致时,文件系统被标记为“错误”。文件系统检查器会测试此项以强制检查文件系统,而不管其表面上是否处于“已清理”状态。
始终跳过文件系统检查有时可能很危险,因此 Ext2fs 提供了两种方法来强制定期检查。超级块中维护了一个挂载计数器。每次文件系统以读/写模式挂载时,此计数器都会递增。当它达到最大值(也记录在超级块中)时,即使文件系统处于“已清理”状态,文件系统检查器也会强制检查。超级块中还维护了上次检查时间和最大检查间隔。这两个字段允许管理员请求定期检查。当达到最大检查间隔时,检查器将忽略文件系统状态并强制执行文件系统检查。
一个属性允许用户请求对文件进行安全删除。当删除此类文件时,随机数据会写入先前分配给该文件的磁盘块中。这可以防止恶意人员通过使用磁盘编辑器访问文件的先前内容。
最后,最近已将受 4.4 BSD 文件系统启发的新文件类型添加到 Ext2fs 中。不可变文件只能读取:任何人都无法写入或删除它们。这可用于保护敏感的配置文件。追加专用文件可以在写入模式下打开,但数据始终追加到文件末尾。与不可变文件一样,它们无法删除或重命名。这对于只能增长的日志文件特别有用。
Ext2 文件系统的物理结构受到 BSD 文件系统布局的强烈影响。文件系统由块组组成。块组类似于 BSD FFS 的柱面组。但是,块组与磁盘上块的物理布局无关,因为现代驱动器倾向于针对顺序访问进行优化,并向操作系统隐藏其物理几何结构。
,---------+---------+---------+---------+---------, | Boot | Block | Block | ... | Block | | sector | group 1 | group 2 | | group n | `---------+---------+---------+---------+---------'
每个块组都包含关键文件系统控制信息(超级块和文件系统描述符)的冗余副本,并且还包含文件系统的一部分(块位图、inode 位图、inode 表的一部分和数据块)。块组的结构在此表中表示
,---------+---------+---------+---------+---------+---------, | Super | FS | Block | Inode | Inode | Data | | block | desc. | bitmap | bitmap | table | blocks | `---------+---------+---------+---------+---------+---------'
使用块组在可靠性方面是一个巨大的胜利:由于控制结构在每个块组中复制,因此可以很容易地从超级块已损坏的文件系统中恢复。这种结构也有助于获得良好的性能:通过减小 inode 表和数据块之间的距离,可以减少文件 I/O 期间的磁盘磁头寻道。
在 Ext2fs 中,目录被管理为可变长度条目的链表。每个条目都包含 inode 编号、条目长度、文件名及其长度。通过使用可变长度条目,可以实现长文件名,而不会浪费目录中的磁盘空间。
在 Linux 中,Ext2fs 内核代码包含许多性能优化,这些优化往往可以提高读取和写入文件时的 I/O 速度。
Ext2fs 利用缓冲区缓存管理执行预读:当必须读取块时,内核代码会请求对多个连续块执行 I/O。这样,它试图确保要读取的下一个块已经加载到缓冲区缓存中。预读通常在文件上的顺序读取期间执行,Ext2fs 将它们扩展到目录读取,无论是显式读取(readdir(2)
调用)还是隐式读取(namei
内核目录查找)。
Ext2fs 还包含许多分配优化。块组用于将相关的 inode 和数据聚集在一起:内核代码始终尝试将文件的数据块分配到与其 inode 相同的组中。这旨在减少内核读取 inode 及其数据块时进行的磁盘磁头寻道。
当向文件写入数据时,Ext2fs 在分配新块时最多预分配 8 个相邻块。即使在非常满的文件系统上,预分配命中率也约为 75%。这种预分配在重负载下实现了良好的写入性能。它还允许将连续块分配给文件,从而加快了未来的顺序读取。
这两种分配优化产生了非常好的局部性
Ext3 支持与 Ext2 相同的功能,但也包括日志功能。您可以从 ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/ 下载预发布版本。
作者现在在 Be Inc 工作,因此您不会看到他在 Web 上更新更多关于 ext2 和 NTFS 文件系统支持的信息。这些驱动程序将被拉入未来的 BeOS 版本中。