如何使用 C++ 代码中的 BTRFS 写入时复制?

Posted

技术标签:

【中文标题】如何使用 C++ 代码中的 BTRFS 写入时复制?【英文标题】:How can I use the Copy on Write of a BTRFS from C++ code? 【发布时间】:2018-10-11 18:03:10 【问题描述】:

如何使用 C++ 在 BTRFS 文件系统中的文件上从假定支持的 Linux 系统上的 C++ 代码复制文件?该解决方案是否适用于所有 Unix 系统?

文件系统的 C++ 标准的任何部分都没有包含 CoW。它也没有出现在 Linux 的文档中,也不是 POSIX 标准。

事实上,即使 GNU cp 实用程序可以处理写入时复制,它也可能并不总是执行,因为它需要一个参数,即--reflink=true 来强制使用它

因此,使用 CoW 很可能需要使用低级原语,显然没有为 Linux 或更广泛的 POSIX 准备文档。

【问题讨论】:

我对你想要做什么感到困惑。在 btrfs 文件系统上写入文件,您将自动获得写入时的副本。它是文件系统的一个功能。 您的 btrfs 文件系统是否使用 nodatacow 挂载并希望特定文件使用 COW? 这可能是相关的:unix.stackexchange.com/questions/394973/… @drescherjm 因为cp Unix 实用程序被记录为在某些属性参数下不使用写入时复制,我猜想可以进行一些系统调用微调,但我找不到任何文档。您可能还注意到我专门用 C++ 说话,因此您提出的内容与此相去甚远 我想解释一个非常具体的问题,其答案是(我找到了)一对系统调用,这几乎是人们在 *** 中可以找到的最狭窄的答案类型可以结束被标记为过于宽泛。 【参考方案1】:

你可以看到cp --reflink=always notes.txt notes.txt.backupstrace完成了哪些系统调用。

因此,如果您运行 strace cp --reflink=always notes.txt notes.txt.backup,您可以在输出中找到:

openat(AT_FDCWD, "notes.txt", O_RDONLY) = 3
fstat(3, st_mode=S_IFREG|0664, st_size=760, ...) = 0
openat(AT_FDCWD, "notes.txt.backup", O_WRONLY|O_TRUNC) = 4
fstat(4, st_mode=S_IFREG|0664, st_size=0, ...) = 0
ioctl(4, BTRFS_IOC_CLONE or FICLONE, 3) = 0

ioctl 调用是创建文件的显式 CoW 副本的 CoW 魔法。

您可以阅读man ioctl_ficlone

【讨论】:

以上是关于如何使用 C++ 代码中的 BTRFS 写入时复制?的主要内容,如果未能解决你的问题,请参考以下文章

btrfs及压缩工具

btrfs文件系统的简单使用方法

btrfs文件系统学习总结

btrfs

Btrfs学习笔记

btrfs文件系统学习