校验和

从 2012 年初开始,元数据校验和被添加到所有主要的 ext4 和 jbd2 数据结构中。相关的特性标志是 metadata_csum。所需的校验和算法在超级块中指明,尽管截至 2012 年 10 月,唯一支持的算法是 crc32c。一些数据结构没有足够的空间来存储完整的 32 位校验和,因此只存储了较低的 16 位。启用 64 位特性会增加数据结构的大小,以便许多数据结构可以存储完整的 32 位校验和。然而,现有的 32 位文件系统无法扩展以启用 64 位模式,至少在没有实验性的 resize2fs 补丁的情况下无法做到。

通过对底层设备运行 tune2fs -O metadata_csum,现有文件系统可以添加校验和功能。如果 tune2fs 遇到缺少足够空白空间来添加校验和的目录块,它将请求您运行 e2fsck -D 以使用校验和重建目录。这样做的一个额外好处是消除了目录文件中的松散空间并重新平衡了 htree 索引。如果您_忽略_此步骤,您的目录将不受校验和保护!

下表描述了每种校验和类型包含的数据元素。校验和函数由超级块描述(截至 2013 年 10 月为 crc32c),除非另有说明。

元数据

长度

组成元素

超级块

__le32

直到校验和字段的整个超级块。UUID 位于超级块内。

MMP

__le32

UUID + 直到校验和字段的整个 MMP 块。

扩展属性

__le32

UUID + 整个扩展属性块。校验和字段设置为零。

目录项

__le32

UUID + inode 号 + inode 代数 + 直到包含校验和字段的伪条目的目录块。

HTREE 节点

__le32

UUID + inode 号 + inode 代数 + 所有有效 extent + HTREE 尾部。校验和字段设置为零。

Extent

__le32

UUID + inode 号 + inode 代数 + 直到校验和字段的整个 extent 块。

位图

__le32 or __le16

UUID + 整个位图。校验和存储在组描述符中,如果组描述符大小为 32 字节(即非 64 位),则会被截断。

Inode

__le32

UUID + inode 号 + inode 代数 + 整个 inode。校验和字段设置为零。每个 inode 都有自己的校验和。

组描述符

__le16

如果 metadata_csum,则为 UUID + 组号 + 整个描述符;否则如果 gdt_csum,则为 crc16(UUID + 组号 + 整个描述符)。在所有情况下,只存储较低的 16 位。