如果在移动文件时中断,文件系统会变得不一致吗?

gra*_*y92 14 filesystems ext2 crash failure-resistance move

我在同一个分区 (EXT2) 上有两个文件夹 如果我mv folder1/file folder2和某些中断发生(例如电源故障),文件系统最终会不一致吗?

mv操作不是原子的吗?

更新: 到目前为止,在 IRC 上我得到了以下观点:

  1. 它是原子的,因此不会发生不一致
  2. 首先您复制新目录中的目录条目,然后擦除前一个目录中的条目,因此您可能会出现两次引用文件的不一致,但引用计数为 1
  3. 它首先擦除指针,然后复制指针,因此不一致之处在于文件的引用为 0

有人可以澄清吗?

Ran*_*832 13

重命名操作在任何文件系统上都非常快,因此不太可能被中断,但在经典文件系统上它肯定可以被中断 - 如果它首先创建目标链接,它可能会在一个文件上留下两个链接 - 这是合法的,但该文件认为它只有一个,如果以后删除一个,这可能会导致问题。另一方面,如果它先删除源链接,则文件可能会丢失。运行 fsck 通常会检测并纠正任何一种情况,但如果文件丢失,它将被放置在具有任意名称的“lost+found”目录中,而不是在所需的位置 - 如果它有两个链接,链接计数将简单地被更新,所以如果文件系统支持,文件将存在于两个位置。

如果您需要一个文件系统在断电时保持稳健,您应该使用日志文件系统,例如 NTFS、EXT3 或 XFS。大多数现代系统默认使用日志文件系统,但您应该知道,如果将 FAT 用于外部驱动器,则它不是日志文件系统。

日志文件系统使用“双重条目”系统 - 它将打算移动它的事实写入日志文件,然后执行移动。在启动时检查文件系统时,如果它被中断,它会注意到移动未完成并重做。

有两种类型的日志文件系统 - 元数据日志和完整日志。元数据日志意味着它不会跟踪日志系统中文件内容的更改(因此,如果您正在写入文件,最终可能会丢失内容),但它仍会跟踪重要的文件系统信息,例如目录内容、文件属性等。


当人们谈论重命名操作是原子的时,他们的意思是系统上的另一个进程无法在转换过程中观察到它,并且不能通过例如mv^C. 写入每个目录的物理过程,其存储空间可能位于磁盘上的不同位置,在硬件级别不可能是真正的原子操作。


为了完整起见,我会注意到除了在目标目录中创建新链接并在旧目录中删除它之外,还有一些与重命名相关的附带 I/O 操作 - 更新两个目录的 mtime,可能会扩展目标目录的分配大小,..如果文件是目录,则更改父目录的链接和链接计数。另外,我不确定文件本身的时间是否受到影响。


Gil*_*il' 11

首先,让我们消除一些神话。

它是原子的,因此不会发生不一致

在同一个文件系统(即rename)系统调用中移动文件对于软件环境来说是原子的。原子性意味着任何查找文件的进程将在其旧位置或新位置看到它;没有进程将能够观察到文件具有不同的链接数,或者文件存在于目标目录中后存在于源目录中,或者文件在源目录中不存在后又不存在于目标目录中目录。

但是,如果系统由于错误、磁盘错误或断电而崩溃,则无法保证文件系统保持一致状态,更不用说移动没有完成一半了。Linux 通常不保证硬件事件的原子性。

首先您复制新目录中的目录条目,然后擦除前一个目录中的条目,因此您可能会出现两次引用文件的不一致,但引用计数为 1

这是指一种特定的实现技术。还有其他人。

碰巧Linux上的ext2(从内核 3.16 开始)使用了这种特殊技术。但是,这并不意味着磁盘内容经过序列 [旧位置] ?[两个地点] ? [新位置],因为这两个操作(添加新条目,删除旧条目)在硬件级别也不是原子的:其中之一可能会被中断,从而使文件系统处于不一致的状态。(希望 fsck 能够修复它。)此外,块层可以重新排序写入,因此前半部分可以在崩溃之前提交到磁盘,而后半部分不会被执行。

只要系统没有崩溃(见上文),引用计数就永远不会被观察到与 1 不同,但这种保证不会扩展到系统崩溃。

它首先擦除指针,然后复制指针,因此不一致之处在于文件的引用为 0

再一次,这指的是一种特定的实现技术。如果系统没有崩溃,则无法观察到悬空文件,但这可能是系统崩溃的结果,至少在某些配置中是这样。


根据Alexander Larsson 的一篇博客文章,ext2 不能保证系统崩溃时的一致性,但 ext3 在该data=ordered模式下可以。(请注意,这篇博文不是关于rename它本身,而是关于写入文件和调用rename该文件的组合。)

ext2、ext3 和 ext4 文件系统的主要作者 Theodore Ts'o就同​​一问题撰写了一篇博文。这篇博文讨论了原子性(仅与软件环境相关)和持久性(即与崩溃相关的原子性加上承诺保证,即知道操作已执行)。不幸的是,我无法找到仅与崩溃有关的原子性信息。但是,为 ext4 提供的持久性保证要求它rename是原子的。ext4 的内核文档指出,带有auto_da_alloc选项的ext4 (现代内核中的默认设置)以及 ext4 为write后跟一个rename,这意味着rename对于硬件崩溃来说是原子的。

为增加了Btrfs,一个rename覆写现有文件被保证是原子相对于崩溃,但一个rename不覆盖文件可导致既不文件或现有这两个文件。


总而言之,您的问题的答案不仅是在 ext2 上移动文件不是原子性的,而且甚至不能保证使文件保持一致状态(尽管fsck无法修复的故障很少见)-几乎什么都不是,这就是为什么发明了更好的文件系统。Ext3、ext4 和 btrfs 确实提供了有限的保证。