2

I'm experiencing a very weird Btrfs "send" issue with file reflinks, and after so many trials, I found the details:

First, I created a subvolume called "1":

btrfs subvolume create 1

and dd a file in it:

dd if=/dev/urandom of=1/a bs=64 count=3110017

Now make a read-only snapshot by sudo btrfs subvolume snapshot -r 1 1_ro0, and then do cp --reflink=always 1/a 1/b, make a ro snapshot again: sudo btrfs subvolume snapshot -r 1 1_ro1. Now count the data size from "btrfs send":

sudo btrfs send -p 1_ro0 1_ro1 | wc -c

It outputs 64864765, which is about 61.9MiB. This's so abnormal - I just copied it using reflink, I don't know why "btrfs send" outputs so much data.

However, if the count above in dd is replaced with 3110016 (3110017-1), then did the routines above again, with wc -c on "btrfs send", you can get 604 (604 B), only 604 bytes, and this is what I expect.

I also made a bash script to do those two tests:

#!/bin/bash

btrfs subvolume create 1

rm -rf 1/*
dd if=/dev/urandom of=1/a bs=64 count=3110017
sudo btrfs subvolume snapshot -r 1 1_ro0
cp --reflink=always 1/a 1/b
sudo btrfs subvolume snapshot -r 1 1_ro1
sudo btrfs send -p 1_ro0 1_ro1 | wc -c
sudo btrfs subvolume delete 1_ro0 1_ro1


rm -rf 1/*
dd if=/dev/urandom of=1/a bs=64 count=3110016
sudo btrfs subvolume snapshot -r 1 1_ro0
cp --reflink=always 1/a 1/b
sudo btrfs subvolume snapshot -r 1 1_ro1
sudo btrfs send -p 1_ro0 1_ro1 | wc -c
sudo btrfs subvolume delete 1_ro0 1_ro1

rm -r 1

If replace wc -c with btrfs receive --dump to inspect the "btrfs send" output data, with dd 3110016 value it will output a few "clone" entries like this:

clone           ./1_ro1/b                       offset=0 len=134217728 from=./1_ro1/a clone_offset=0
clone           ./1_ro1/b                       offset=134217728 len=64823296 from=./1_ro1/a clone_offset=134217728
...

But with dd value 3110017, it outputs:

write           ./1_ro1/b                       offset=197918720 len=49152
write           ./1_ro1/b                       offset=197967872 len=49152
write           ./1_ro1/b                       offset=198017024 len=49152
write           ./1_ro1/b                       offset=198066176 len=49152
write           ./1_ro1/b                       offset=198115328 len=49152
write           ./1_ro1/b                       offset=198164480 len=49152
... (so many more)

which contains a bunch of "write" entries.

I also searched and noticed this site: https://www.spinics.net/lists/linux-btrfs/msg105951.html, and it's like talking about file holes, but in my case it obviously can't be.

This is so weird and I don't know what I'm missing.

My btrfs-progs version is 5.18.1-1

and the mount options from /proc/mount: rw,relatime,space_cache=v2,subvolid=5,subvol=/

Thanks!

bczhc
  • 21
  • 3
  • Talks on Reddit: https://www.reddit.com/r/btrfs/comments/wljt4s/btrfs_send_breaks_reflinks – bczhc Dec 20 '22 at 08:45

0 Answers0