Posts Tagged ‘per-file’

Using btrfs per-file and per-directory compression

Wednesday, August 31st, 2011

According to btrfs wiki per-file and per-directory compression has been added in 2.6.39 kernel (May 2011). I have spent a lot of time on searching how to use this. I had no luck with googling on this subject but after digging deeper and deeper it turns out that it’s actually very simple solution.

You may not know or remember that linux actually has “file attributes”. You may also not remember that they are very easy to use with some small CLI tools like “lsattr” and “chattr” which you most probably already have installed on your linux machine. Of course there is also a “compress” attribute which you can use.

So to enable compression for a certain file or directory do:

chattr +c <filename>

and to disable compression do:

chattr -c <filename>

Of course this doesn’t do anything to the existing file or directory. Setting the compression flag means that data that will be written from now on will be compressed. So if you consider the following commands:

cat /dev/zero > test
chattr +c test
cat /dev/zero >> test

You will find that data written by the first cat remains uncompressed and data written by the second cat is compressed. Of course you have to stop cat commands at some point with CTRL+C. You can check this behavior by letting cat work for a relatively long time and watching the file size and the disk free space in the meantime (or just the hdd led maybe).

However if you do the following succession:

cat /dev/zero > test
chattr +c test
echo 0 >> test
echo 0 >> test
cat /dev/zero >> test
lsattr chattr +c test

You will find that the second cat still writes uncompressed and lsattr doesn’t list the “c” flag as enabled. The last chattr command will produce “Invalid argument while setting flags on test”. This is probably a bug in the kernel version that I have (3.0.3-zen). If you echo 2 zeros instead of 2 echos with single zero this bug doesn’t appear. Before the last cat things also seem to be in order.