File Copy Btrfs – How to Verify a File Copy is Reflink/CoW?

btrfsfile-copy

I'm playing with btrfs, which allows cp --reflink to copy-on-write. Other programs, such as lxc-clone, may use this feature as well. My question is, how to tell if a file is a CoW of another? Like for hardlink, I can tell from the inode number.

Best Answer

Good question. Looks like there aren't currently any easy high-level ways to tell.

One problem is that a file may only share part of the data via Copy-on-Write. This is called a physical extent, and some or all of the physical extents may be shared between CoW files.

There is nothing analogous to an inode which, when compared between files, would tell you that the files share the same physical extents. (Edit: see my other answer).

The low level answer is that you can ask the kernel which physical extents are used for the file using the FS_IOC_FIEMAP ioctl, which is documented in Documentation/filesystems/fiemap.txt. In principle, if all of the physical extents are the same, then the file must be sharing the same underlying storage.

Few things implement a way to look at this information at a higher level. I found some go code here. Apparently the filefrag utility is supposed to show the extents with -v. In addition, btrfs-debug-tree shows this information.

I would exercise caution however, since these things may have had little use in the wild for this purpose, you could find bugs giving you wrong answers, so beware relying on this data for deciding on operations which could cause data corruption.

Some related questions: