孤立文件

在 Unix 系统中,有些 inode 可能已从目录层级中解除链接,但由于仍被打开而依然存在。如果系统崩溃,文件系统必须清理这些 inode,否则它们(以及它们引用的块)将会泄露。同样,如果我们要截断或扩展文件,可能无法在一个单独的日志事务中完成操作。在这种情况下,我们将 inode 标记为孤立的,以便在系统崩溃时,分配给文件的额外块可以被截断。

传统上,ext4 文件系统以单向链表的形式跟踪孤立 inode,其中超级块包含最后一个孤立 inode 的 inode 号(s_last_orphan 字段),然后每个 inode 包含前一个孤立 inode 的 inode 号(我们为此重载了 i_dtime inode 字段)。然而,对于导致大量孤立 inode 生成的工作负载,这种文件系统全局单向链表是可伸缩性的瓶颈。当启用孤立文件特性(COMPAT_ORPHAN_FILE)时,文件系统会有一个特殊的 inode(通过 s_orphan_file_inum 从超级块引用),它包含多个块。每个块都具有以下结构:

偏移量

类型

名称

描述

0x0

__le32 条目数组

孤立 inode 条目

每个 __le32 条目要么为空(0),要么包含一个孤立 inode 的 inode 号。

blocksize-8

__le32

ob_magic

存储在孤立块尾部的魔术值 (0x0b10ca04)

blocksize-4

__le32

ob_checksum

孤立块的校验和。

当一个启用了孤立文件特性的文件系统以可写方式挂载时,我们会在超级块中设置 RO_COMPAT_ORPHAN_PRESENT 特性,以表明可能存在有效的孤立条目。如果在挂载文件系统时看到此特性,我们会像往常一样读取整个孤立文件并处理其中找到的所有孤立 inode。当干净地卸载文件系统时,我们会移除 RO_COMPAT_ORPHAN_PRESENT 特性,以避免对孤立文件进行不必要的扫描,并使文件系统与旧内核完全兼容。