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. 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!
More discussions on Reddit can be referred to. https://www.reddit.com/r/btrfs/comments/wljt4s/btrfs_send_breaks_reflinks
Answer from the mailing list: https://lore.kernel.org/linux-btrfs/20221008005704.795b44b0@crass-HP-ZBook-15-G2/ So I think this issue can be closed.
https://github.com/kdave/btrfs-progs/issues/572 for adding the answer to the documentation.