Why does “cp -R –reflink=always” perform a standard copy on a btrfs filesystem

btrfscp

Btrfs support Copy-On-Write. I tried to use that feature to clone a directory:

cp -R --reflink=always foo_directory foo_directory.mirror

I expected the command to finish almost instantly (like a btrfs subvolume snapshot), but the cp command seems to perform a slow, standard copy.

According to the man page, I would expected --reflink=always to enforce Copy-On-Write:

When –reflink[=always] is specified, perform a lightweight copy, where the data blocks are copied only when modified. If this is not possible the copy fails, or if –reflink=auto is specified, fall back to a standard copy.

Questions:

  • Do you know why --reflink=always doesn't work?
  • What options (or other commands) should I use instead?

Best Answer

cp --reflink=always is almost certainly working correctly. If it weren't, you would be getting an error. By design, that's the difference between --reflink=always and --reflink=auto. The error would look like this:

# Filesystem that does not support the feature at all
cp: failed to clone `xx' from `yy': Inappropriate ioctl for device

# Filesystem that does support it, but copy across filesystems
cp: failed to clone `xx' from `yy': Invalid cross-device link

Are you copying a directory structure with lots of small files? In that case cp still has to create every directory and open and close every file, so it will still take time, unlike btrfs subvolume snapshot. That most likely explains the time it takes to perform the operation.

Related Question