在 RHEL/CentOS 7 中,mv 实际上是否在同一文件系统上执行 cp 和 rm 操作?

在 RHEL/CentOS 7 中,mv 实际上是否在同一文件系统上执行 cp 和 rm 操作?

根据两个问题的答案以前的 问题, 它似乎在 RHEL/CentOS 7 下,mv即使在同一文件系统上,实际上也在执行cpthen rm.

在以前版本的 CentOS/RHEL 中,mv即使在处理大型文件(例如安装媒体或大型视频的集合)时,同一文件系统(甚至从深层目录到新的深层目录)的速度也非常快。

然而,在我个人的 CentOS 服务器上,当查看mv移动大文件时实际执行的操作时,需要花费cp长达rm.

这让我想知道为什么这种行为显然已经从只是一个包装器变成了rename()(根据POSIX标准)。

它是否正确?如果是这样,为什么该mv实用程序会改变 CentOS 7 中的行为?

答案1

CentOS 7.2mv命令将尝试使用该rename(3)调用。

例如,如果我这样做strace mv X Y,那么我会在输出中看到

rename("X", "Y")                        = 0

这样我们就可以看到mvrename调用成功了。

如果我尝试将此目录重命名为另一个磁盘:

rename("X", "/home/sweh/X")             = -1 EXDEV (Invalid cross-device link)

我们可以看到mv尝试使用该rename()调用但失败了。此时就开始做递归工作

rmdir("/home/sweh/X")                   = -1 ENOENT (No such file or directory)
mkdir("/home/sweh/X", 0700)             = 0
lstat("/home/sweh/X", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
openat(AT_FDCWD, "X", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
getdents(3, /* 2 entries */, 32768)     = 48

在这里我们可以看到它已成为目标目录,然后开始读取当前目录以进行慢速复制/删除。

因此我们可以得出结论,mv将尝试使用快速rename()调用,只有在失败时才回退到慢速版本。

相关内容