在受到广泛投诉之后,ext4 获得了一种名为auto_da_alloc
默认启用的碰撞安全保证。其他文件系统呢?在最著名的文件系统中,哪些提供了相同的保证(哪些没有)?
我个人有兴趣听到有关
根据以下历史记录,此问题主要与 Linux 相关。了解 ZFS 的行为方式也会很有趣,但我倾向于假设它不会实现这一点。
auto_da_alloc
?fsync() 被充分记录为写入文件数据的正确方法,例如当您在文本编辑器中点击“保存”时。并且众所周知,例如文本编辑器必须使用 rename() 原子地替换现有文件。这是为了防止断电,确保您始终保留旧文件或获取新文件(在重命名之前进行 fsync() 处理)。您不想只留下新文件的一半编写版本。
但是存在一个问题,即在最流行的 Linux 文件系统 ext3 上调用 fsync() 会有效地使整个系统挂起数十秒。由于应用程序对此无能为力,因此乐观地使用 rename() 而不使用 fsync() 是很常见的。即使系统断电,这种模式在这个文件系统上似乎也能很好地工作。
因此,存在未正确使用 fsync() 的应用程序。
文件系统的下一个版本 ext4 通常避免了 fsync() 挂起。同时,它开始更多地依赖于 fsync() 的正确使用。
这一切都非常糟糕。许多相互冲突的内核开发人员使用的不屑一顾的短语可以说无助于理解这段历史。
这已在 ext4 中解决,以 支持 rename() 模式而不需要 fsync() 以确保碰撞安全像旧的 ext3 文件系统那样提供崩溃时的行为。如果您使用选项挂载,则可以再次禁用此行为noauto_da_alloc
。
这个问题有一个错误。现在的问题暗示,这种情况下是由完全崩溃安全通过auto_da_alloc
。对于 ext4,情况并非如此。我认为在旧的 ext3 中也不是这样。然而,对于 btrfs 和 bcachefs都是如此。
最近的 ext4 确实有一个特殊的解决方法,可以通过在 rename 时强制删除新数据块来减少 replace-via-rename 产生零长度文件的机会。但是,重命名不会等待刷新完成,因此不提供原子性保证——崩溃后可能最终只得到部分新内容。在我们测试的文件系统中,btrfs 是唯一提供替换通过重命名原子性保证的文件系统。
https://homes.cs.washington.edu/~lijl/papers/ferrite-asplos16.pdf
在 上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
归档时间: |
|
查看次数: |
2591 次 |
最近记录: |