2

How can I copy a file using copy on write using C++ over a file in a BTRFS filesystem from C++ code on a Linux system that is assumed to support it? Is the solution generic to all Unix systems?

CoW is not included at all in any part of the C++ standard for filesystems. It is not present either in the documentation of Linux, and is not POSIX standard either.

In fact, even if the GNU cp utility can handle copy on write, it may not always be performed since it require an argument, namely --reflink=true to force its usage

As such, using CoW will very likely need to use low level primitives for which apparently no documentation for Linux or more broadly POSIX have been prepared.

  • I am confused at what you are trying to do. Writing a file that is on a btrfs filesystem you will have copy on write automatically. Its a function of the filesystem. – drescherjm Oct 11 '18 at 18:12
  • Is your btrfs file system mounted with `nodatacow` and want specific files to use COW? – drescherjm Oct 11 '18 at 18:14
  • This may be related: https://unix.stackexchange.com/questions/394973/why-would-i-want-to-disable-copy-on-write-while-creating-qemu-images – drescherjm Oct 11 '18 at 18:15
  • @drescherjm since the `cp` Unix utility is documented as not using copy on write under certain attribute parameters, I guessed that some system call fine tweaking is possible, yet I could not find any documentation. You may also notice that I speak specifically in C++, hence what you propose is very far from related – Ludovic Zenohate Lagouardette Oct 11 '18 at 18:21
  • I would like an explanation about how a very specific questions, whose answer is (I found it) a pair of system calls which is pretty much the most narrow type of answer one can find in stackoverflow can end up labeled as too broad. – Ludovic Zenohate Lagouardette Oct 13 '18 at 07:18
  • @LudovicZenohateLagouardette Can you edit your question to include the information about ``cp`` you posted in the comments? To me, your question did read as very unclear; I was unable to figure out what you mean, because CoW is an internal filesystem mechanism, and I did not know that there’s a way to make use of explicitly it at all. This is a very good question IMO and very useful, too. Once edited, I think it could be re-opened. – Jonas Schäfer Oct 13 '18 at 08:18
  • @LudovicZenohateLagouardette: can you post the answer you found? – Michael Burr Oct 13 '18 at 23:40

1 Answers1

3

You can see what system calls are done by cp --reflink=always notes.txt notes.txt.backup with strace.

So if you run strace cp --reflink=always notes.txt notes.txt.backup you can find this in the output:

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

That ioctl call is the CoW magic that creates an explicit CoW copy of a file.

You can read man ioctl_ficlone

David Foerster
  • 1,461
  • 1
  • 14
  • 23
Zan Lynx
  • 53,022
  • 10
  • 79
  • 131