为什么 cp --reflink=auto 不是默认行为?

Fab*_*nze 53 coreutils btrfs

为什么cp --reflink=auto不是默认行为?启用它会造成任何伤害吗?

是否可以在编译时启用它,以便在整个系统中使用它,而不仅仅是在交互式 shell 中使用?

Pád*_*ady 57

这不是默认设置,因为出于健壮性原因,人们可能希望进行复制以防止数据损坏。同样出于性能原因,您可能希望写入发生在复制时,而不是一些处理 CoW 文件的延迟敏感过程,并且可能会被写入机械磁盘的不同部分而延迟。请注意,从 coreutils v8.24 mv 将默认重新链接,因为它没有上述约束。另请注意,v8.32之后的主要版本将默认尝试在 cp 中重新链接,因为这样的更改不适用于次要版本。

  • (这可以被视为权威答案,因为 Pádraig 是 GNU coreutils 的维护者)。 (20认同)
  • 我怀疑这个答案是否正确,至少在 btrfs 上是这样。如果稍后写入文件,由于 btrfs CoW,新数据无论如何都会写入不同的磁盘扇区,因此不进行 reflinks 没有延迟优势。无论如何都无法重新链接设置了 NoDataCoW 的文件。如果你想防止数据损坏,你需要复制到不同的分区,reflinks 也不起作用。 (10认同)
  • 由于 BTRFS 需要在写入时查找和分配空间,因此存在延迟问题。这甚至可能不可用,从而在写入时抛出 ENOSPC 错误 (5认同)
  • btrfs 上的跨子卷重命名 (4认同)
  • mv 对 reflink 有什么用? (3认同)
  • @PádraigBrady 据我所知,Btrfs 总是需要在写入时查找和分配空间(至少在默认情况下以及可能和/或有意义的时候),因为它是一个 CoW 文件系统。因此,如果您不将 reflink 与 Btrfs 一起使用,无论如何您最终都会得到一个 CoW 文件(除了您从头开始而不是重用原始文件中的块)。 (2认同)

Sté*_*las 18

不知道为什么它不是默认值,可能是因为它的行为与其他不支持它的复制实用程序(rsync, cpio, pax, tar...)相同(或者当文件通过不允许这样做的接口复制时) (如 NFS、samba、融合文件系统层......)。

几年前我也处于同样的情况,快速查看 GNU cp 代码,它仍然相同,您必须修补代码以获得不同的默认行为:

--- coreutils-8.21/src/cp.c~    2013-06-22 21:50:26.265639114 +0100
+++ coreutils-8.21/src/cp.c     2013-06-22 21:51:06.880513924 +0100
@@ -775,7 +775,7 @@ cp_option_init (struct cp_options *x)
   x->interactive = I_UNSPECIFIED;
   x->move_mode = false;
   x->one_file_system = false;
-  x->reflink_mode = REFLINK_NEVER;
+  x->reflink_mode = REFLINK_AUTO;

   x->preserve_ownership = false;
   x->preserve_links = false;
Run Code Online (Sandbox Code Playgroud)


Bru*_*ams 11

从 coreutils 9.0 开始,reflink=auto 是默认行为。看:

https://lists.gnu.org/archive/html/info-gnu/2021-09/msg00010.html

这是为了发布 coreutils-9.0,一个稳定版本。

这是一个新的主要版本,具有以下重大变化:

  • cp 改变了它处理数据的方式
    • 默认启用 CoW(通过 FICLONE ioctl),
    • 在可用的情况下使用复制卸载(通过 copy_file_range),
    • 检测孔的方式不同(尽管 SEEK_HOLE)
    • 这也适用于 mv 和 install。


小智 5

alias cp='cp --reflink=auto --sparse=always'
Run Code Online (Sandbox Code Playgroud)

比修补代码更有意义

  • 看起来您忽略了_是否可以在编译时启用它,因此它在整个系统中使用,而不仅仅是在 OP 问题中的交互式 shell 中使用。 (6认同)
  • @StephaneChazelas One 总是可以重命名 `/bin/cp` 并用类似的 shell 脚本替换它 (5认同)