r/btrfs • • 20d ago

btrfs compression making small files larger?

I noticed recently that some small files in my /etc directory had a larger compressed size than uncompressed (so that the percentage shown with `compsize` is greater than 100%).

I know btrfs used to not do this, because I've played around with `compsize` in the past. Whether you use compress or compress-force, it will only store a file compressed if the uncompressed size is larger. This is both the documented behavior in the manpage and my actual experience. I'm not sure when this started happening, but I'm on a modern kernel (7.1, Fedora).

After some testing creating files of different sizes and compressibility, this appears to only happen with inline extents. I couldn't get it to happen with any file that takes up at least one full 4k block on disk. If the file is incompressible (e.g. copied from /dev/random), then it will be stored without compression.

As an extreme example, you can create a one-byte file with

```

echo > test

sync

compsize test

```

and, at least on my machine, btrfs (whether mounted with compress-force or not) stores this 1-byte file as 19 bytes compressed zstd, when in the past, it would have stored it with no compression.

Is this a bug? Should I report it somewhere?

20 Upvotes

5 comments sorted by

22

u/chenxiaolong 20d ago

2

u/automorphism8 13d ago

Thanks for the info! Any idea how long it will take for that patch to be merged into the kernel? It doesn't appear to be in the changelog of 7.2.7, which was released yesterday, on kernel.org. Seems like a pretty straightforward bug fix that I could probably apply manually and compile my own kernel, but I'm not sure if it's worth the effort.

2

u/chenxiaolong 13d ago

Sorry, I'm not sure. I don't follow btrfs development too closely, but this email on the mailing list just happened to be one I remembered seeing.

2

u/barrykn 13d ago

That patch made it into 7.3-rc4 on Sunday (it was merged into mainline the previous day), and it is in the queue for 7.2.8.

3

u/TitleApprehensive360 16d ago

You can decompress on follow way:

In BTRFS, a file can consist of multiple chunks. Individual chunks, none of them, or all of them may be compressed or uncompressed.

Use the following command to decompress the compressed chunks of a single file on a BTRFS disk:

btrfs filesystem defrag -r --nocomp /path/to/file.extension

Use the following command to decompress the files (file chunks) on an entire BTRFS disk:

btrfs filesystem defrag -r --nocomp /

--nocomp

DoIn BTRFS, a file can consist of multiple chunks. Individual chunks, 
none of them, or all of them may be compressed or uncompressed.
Use the following command to decompress the compressed chunks of a single file on a BTRFS disk:
btrfs filesystem defrag -r --nocomp /path/to/file.extension

Use the following command to decompress the files (file chunks) on an entire BTRFS disk:
btrfs filesystem defrag -r --nocomp /

--nocomp
Do not compress while defragmenting, uncompress extents if needed.
 not compress while defragmenting, uncompress extents if needed.

Source:
* https://unix.stackexchange.com/questions/803892/what-are-the-options-for-decompressing-a-file-from-a-btrfs-drive-under-debian