FICLONE 与 FICLONERANGE 与 copy_file_range 的区别(用于写时复制支持)
Difference of FICLONE vs FICLONERANGE vs copy_file_range (for copy-on-write support)
我想知道复制文件的有效方法(在 Linux,在支持 copy-on-write (COW) 的 FS 上)。
具体来说,我希望我的实现尽可能使用写时复制,否则回退到其他有效的变体。具体来说,我还关心服务器端复制(由SMB, NFS and others), and also zero-copy支持(即如果可能绕过CPU或内存)。
(这个问题并不是真正特定于任何编程语言。它可以是 C 或 C++,也可以是任何其他语言,例如 Python、Go 或任何与 OS 系统调用有绑定的东西,或者有任何方法可以进行系统调用。如果这让您感到困惑,请用 C 回答。)
看起来像 ioctl_ficlonerange
, ioctl_ficlone
(i.e. ioctl
with FICLONE
or FICLONERANGE
) support copy-on-write (COW). Specifically FICLONE
is used by GNU cp
(here,来自 --reflink
)。
然后还有copy_file_range
,好像也支持COW,和server-side-copy。
(LWN about copy_file_range.)
听起来好像 copy_file_range
更通用(例如,它支持服务器端复制;不确定 FICLONE
是否支持)。
但是,copy_file_range
似乎有一些问题。
例如。 here,Paul Eggert 评论:
[copy_file_range]'s man page
says it uses a size_t (not off_t) to count the number of bytes to be
copied, which is a strange choice for a file-copying API.
是否存在 FICLONE
比 copy_file_range
better/different 更有效的情况?
是否存在 FICLONE
比 FICLONERANGE
better/different 更有效的情况?
具体来说,假设底层 FS 支持这个,并假设你想复制一个文件。我问一下这些函数的支持功能为:
- Copy-on-write支持
- 服务器端复制支持
- Zero-copy支持
他们(FICLONE
、FICLONERANGE
、copy_file_range
)是否总是执行完全相同的操作? (假设底层FS支持写时复制,and/or服务器端复制。)
或者是否存在使用 copy_file_range
而不是 FICLONE
有意义的情况? (例如,COW 只适用于 copy_file_range
但不适用于 FICLONE
。或者反过来。或者这永远不会发生?)
或者以不同的方式表述相同的问题:copy_file_range
总是没问题,还是在某些情况下我想改用 FICLONE
?
为什么 GNU cp
使用 FICLONE
而不是 copy_file_range
? (是否有技术原因,或者这只是历史原因?)
相关:GNU cp
原来默认不使用reflink
(参见comment by the GNU coreutils maintainer Pádraig Brady)。
但是,最近发生了变化 (this commit, bug report 24400),即 COW 行为现在是默认行为(如果可能的话)(--reflink=auto
)。
相关.
相关discussion about FICLONE vs copy_file_range by Python developers。 IE。这似乎是一个有效的问题,并且不完全清楚是使用 FICLONE
还是 copy_file_range
.
相关 Syncthing documentation about the choice of methods for copying data between files,以及
Syncthing issue about copy_file_range
and others for efficient file copying, e.g. with COW support。
它还表明,FICLONE
是否会与 copy_file_range
做同样的事情还不是很清楚,因此他们的解决方案是只尝试所有这些,然后按以下顺序回退到下一个:
ioctl(使用 FICLONE),copy_file_range,sendfile,duplicate_extents,标准。
相关issue by Go developers on the usage of copy_file_range
。
听起来好像他们同意 copy_file_range
总是优于 sendfile
。
(从here复制的问题,但我看不出这太不集中了。这个问题非常集中,问了一个非常具体的事情(FICLONE和copy_file_range的行为是否相同), 并且应该非常清楚。我以多种不同的方式提出问题,使问题更加清楚。这个问题也得到了非常好的研究,并且应该已经对社区非常有价值,因为所有参考资料都是如此。当我开始研究 FICLONE 和 copy_file_range 之间的差异时,如果我能自己找到这样一个问题,即使没有答案,我也会很高兴。)
参见 Linux vfs doc 关于 copy_file_range
、remap_file_range
、FICLONERANGE
、FICLONE
和 FIDEDUPERANGE
。
接着看
vfs_copy_file_range
。如果可能,这将首先尝试调用 remap_file_range
。
FICLONE
调用 ioctl_file_clone
(here),
FICLONERANGE
呼叫 ioctl_file_clone_range
。
ioctl_file_clone_range
调用更通用的 ioctl_file_clone
(here)。
ioctl_file_clone
呼叫 vfs_clone_file_range
(here)。
vfs_clone_file_range
调用 do_clone_file_range
并且调用 remap_file_range
(here).
即这回答了问题。 copy_file_range
更通用,无论如何都会首先在内部尝试调用 remap_file_range
(即与 FICLONE
/FICLONERANGE
相同)。
我认为 copy_file_range
系统调用比 FICLONE
稍新,也就是说,copy_file_range
可能在您的内核中不可用,但 FICLONE
可用。
无论如何,如果copy_file_range
可用,那应该是最好的解决方案。
Syncthing (ioctl (with FICLONE), copy_file_range, sendfile, duplicate_extents, standard) 完成的命令是有意义的。
我想知道复制文件的有效方法(在 Linux,在支持 copy-on-write (COW) 的 FS 上)。 具体来说,我希望我的实现尽可能使用写时复制,否则回退到其他有效的变体。具体来说,我还关心服务器端复制(由SMB, NFS and others), and also zero-copy支持(即如果可能绕过CPU或内存)。
(这个问题并不是真正特定于任何编程语言。它可以是 C 或 C++,也可以是任何其他语言,例如 Python、Go 或任何与 OS 系统调用有绑定的东西,或者有任何方法可以进行系统调用。如果这让您感到困惑,请用 C 回答。)
看起来像 ioctl_ficlonerange
, ioctl_ficlone
(i.e. ioctl
with FICLONE
or FICLONERANGE
) support copy-on-write (COW). Specifically FICLONE
is used by GNU cp
(here,来自 --reflink
)。
然后还有copy_file_range
,好像也支持COW,和server-side-copy。
(LWN about copy_file_range.)
听起来好像 copy_file_range
更通用(例如,它支持服务器端复制;不确定 FICLONE
是否支持)。
但是,copy_file_range
似乎有一些问题。
例如。 here,Paul Eggert 评论:
[copy_file_range]'s man page says it uses a size_t (not off_t) to count the number of bytes to be copied, which is a strange choice for a file-copying API.
是否存在 FICLONE
比 copy_file_range
better/different 更有效的情况?
是否存在 FICLONE
比 FICLONERANGE
better/different 更有效的情况?
具体来说,假设底层 FS 支持这个,并假设你想复制一个文件。我问一下这些函数的支持功能为:
- Copy-on-write支持
- 服务器端复制支持
- Zero-copy支持
他们(FICLONE
、FICLONERANGE
、copy_file_range
)是否总是执行完全相同的操作? (假设底层FS支持写时复制,and/or服务器端复制。)
或者是否存在使用 copy_file_range
而不是 FICLONE
有意义的情况? (例如,COW 只适用于 copy_file_range
但不适用于 FICLONE
。或者反过来。或者这永远不会发生?)
或者以不同的方式表述相同的问题:copy_file_range
总是没问题,还是在某些情况下我想改用 FICLONE
?
为什么 GNU cp
使用 FICLONE
而不是 copy_file_range
? (是否有技术原因,或者这只是历史原因?)
相关:GNU cp
原来默认不使用reflink
(参见comment by the GNU coreutils maintainer Pádraig Brady)。
但是,最近发生了变化 (this commit, bug report 24400),即 COW 行为现在是默认行为(如果可能的话)(--reflink=auto
)。
相关
相关discussion about FICLONE vs copy_file_range by Python developers。 IE。这似乎是一个有效的问题,并且不完全清楚是使用 FICLONE
还是 copy_file_range
.
相关 Syncthing documentation about the choice of methods for copying data between files,以及
Syncthing issue about copy_file_range
and others for efficient file copying, e.g. with COW support。
它还表明,FICLONE
是否会与 copy_file_range
做同样的事情还不是很清楚,因此他们的解决方案是只尝试所有这些,然后按以下顺序回退到下一个:
ioctl(使用 FICLONE),copy_file_range,sendfile,duplicate_extents,标准。
相关issue by Go developers on the usage of copy_file_range
。
听起来好像他们同意 copy_file_range
总是优于 sendfile
。
(从here复制的问题,但我看不出这太不集中了。这个问题非常集中,问了一个非常具体的事情(FICLONE和copy_file_range的行为是否相同), 并且应该非常清楚。我以多种不同的方式提出问题,使问题更加清楚。这个问题也得到了非常好的研究,并且应该已经对社区非常有价值,因为所有参考资料都是如此。当我开始研究 FICLONE 和 copy_file_range 之间的差异时,如果我能自己找到这样一个问题,即使没有答案,我也会很高兴。)
参见 Linux vfs doc 关于 copy_file_range
、remap_file_range
、FICLONERANGE
、FICLONE
和 FIDEDUPERANGE
。
接着看
vfs_copy_file_range
。如果可能,这将首先尝试调用 remap_file_range
。
FICLONE
调用 ioctl_file_clone
(here),
FICLONERANGE
呼叫 ioctl_file_clone_range
。
ioctl_file_clone_range
调用更通用的 ioctl_file_clone
(here)。
ioctl_file_clone
呼叫 vfs_clone_file_range
(here)。
vfs_clone_file_range
调用 do_clone_file_range
并且调用 remap_file_range
(here).
即这回答了问题。 copy_file_range
更通用,无论如何都会首先在内部尝试调用 remap_file_range
(即与 FICLONE
/FICLONERANGE
相同)。
我认为 copy_file_range
系统调用比 FICLONE
稍新,也就是说,copy_file_range
可能在您的内核中不可用,但 FICLONE
可用。
无论如何,如果copy_file_range
可用,那应该是最好的解决方案。
Syncthing (ioctl (with FICLONE), copy_file_range, sendfile, duplicate_extents, standard) 完成的命令是有意义的。