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!