0

I want to make a behaviour like btrfs send and btrfs receive, but on a per-file basis. As far as I see it, I can use cp -ax --reflink=always to make a "snapshot" of the file. Let's assume that two such "snapshots" on two different hard disks are exactly equal. How do I cp the diff (and only the diff) between two reflinked files like btrfs send -p would do it?

Ideally, I would like to have a solution that works on any filesystem that is capable of making reflinks and not only on btrfs. Also ideally, I would like to run it without sudo.

I know that I can look at the file extents with filefrag, but filefrag does not guarantee that the results are exact. I would rather copy some megabytes more than taking the risk of a corrupted file.

1 Answers1

0

I have found a workaround (not tested yet):

  1. Create a new subvolume X and a subvolume Y on the original disk.
  2. Use cp -ax --reflink=always to copy the old version to subvolume X and the new one to subvolume Y.
  3. Copy subvolume X to the second disk using btrfs send (if this is the first time you are doing this) or re-create subvolume X from the file as in step 1 and 2 (if not).
  4. Copy subvolume Y to the second disk using btrfs send -p.
  5. Reflink the file inside subvolume Y on the second disk accordingly (replacing the old file) and delete all subvolumes used in the process.

Warning: I'm not sure if this works at all. I'll need extensive testing to ensure that this really does what it should do. In theory, if the creation of subvolumes is 100% reproducible (=performing the same operations twice results in an equivalent internal state of the btrfs tree), it should work.

I would still be happy for a proper solution.


Edit: You can of cause check if filefrag produces the same result on both disks.