在广泛抱怨之后,ext4 获得了auto_da_alloc
默认启用的碰撞安全保证。其他文件系统呢?在最著名的文件系统中,哪些提供相同的保证(哪些不提供)?
就我个人而言,我有兴趣听到关于
- XFS - Red Hat Enterprise Linux 默认文件系统。
- btrfs - SuSE Enterprise 默认文件系统。
- bcachefs - out-of-tree Linux 文件系统,源自 bcache。“不会吃掉你的数据的 Linux 的 COW 文件系统。”
根据下面的历史,这个问题主要与 Linux 有关。了解 ZFS 的行为方式也会很有趣,但我倾向于假设它不会实现这一点。
是什么auto_da_alloc
?
fsync() 被详细记录为写入文件数据的正确方法,例如当您在文本编辑器中点击“保存”时。众所周知,例如文本编辑器必须使用 rename() 原子地替换现有文件。这是为了防止断电,确保您始终保留旧文件或获取新文件(在重命名之前已 fsync()ed)。您不希望只留下新文件的半写版本。
但是有一个问题是,在最流行的 Linux 文件系统 ext3 上调用 fsync() 可以有效地使整个系统挂起数十秒。由于应用程序对此无能为力,因此乐观地使用 rename() 而不使用 fsync() 是很常见的。即使系统断电,这种模式似乎在这个文件系统上运行得相当好。
因此,存在不正确使用 fsync() 的应用程序。
文件系统的下一个版本 ext4 通常避免了 fsync() 挂起。同时,它开始更多地依赖于 fsync() 的正确使用。
这一切都很糟糕。许多相互冲突的内核开发人员使用的不屑一顾的短语可能无助于理解这段历史。
这在 ext4 中得到了解决,到支持 rename() 模式,而不需要 fsync() 来确保崩溃安全提供崩溃时的行为,就像旧的 ext3 文件系统一样。如果您使用选项挂载,则可以再次禁用此行为noauto_da_alloc
。
这个问题有一个错误。这个问题暗示这种情况是完全安全的
auto_da_alloc
。这不适用于 ext4。我认为在旧的 ext3 中也不是这样。但是对于 btrfs 和 bcachefs来说是这样。https://homes.cs.washington.edu/~lijl/papers/ferrite-asplos16.pdf
On
btrfs
,文档说使用 rename() 替换文件将提供完整的原子性,并且不需要显式的 fsync() 来保护数据免受崩溃。我认为这是与 ext4 大约同时添加的auto_da_alloc
。我们还看到声称 btrfs 实现避免了性能下降,因为它不会导致 rename() 调用等待。但是我注意到在最近的内核中,至少如果你使用了 fsync(),下面的 rename() 将fsync() 父目录并等待整个“日志树”被写入。bcachefs
目前似乎提供了全面的保护,尽管我没有找到任何文档。检查代码。 我看到对函数“filemap_write_and_wait_range”的调用XFS
已拒绝为 rename() 添加崩溃安全解决方法。它显然获得了在不同情况下降低(但不消除)数据丢失风险的代码。UBIFS
(例如在许多 Openwrt 设备上使用)不包括 rename() 的任何崩溃安全解决方法。它可以被接受,但需要大量工作。 http://www.linux-mtd.infradead.org/doc/ubifs.html#L_sync_exceptions