Bug 216148 - "btrfs send" output data size is too large and it can vary greatly
Summary: "btrfs send" output data size is too large and it can vary greatly
Status: RESOLVED ANSWERED
Alias: None
Product: File System
Classification: Unclassified
Component: btrfs (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: BTRFS virtual assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-06-19 13:38 UTC by bczhc0
Modified: 2023-01-20 12:44 UTC (History)
2 users (show)

See Also:
Kernel Version: 5.18.5
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description bczhc0 2022-06-19 13:38:12 UTC
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!
Comment 1 bczhc0 2022-08-16 03:10:52 UTC
More discussions on Reddit can be referred to.

https://www.reddit.com/r/btrfs/comments/wljt4s/btrfs_send_breaks_reflinks
Comment 2 bczhc0 2022-12-27 09:39:10 UTC
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.
Comment 3 David Sterba 2023-01-20 12:44:01 UTC
https://github.com/kdave/btrfs-progs/issues/572 for adding the answer to the documentation.

Note You need to log in before you can comment on or make changes to this bug.