Quota for Home Directories in Linux using BTRFS
I have a big drive on a home linux server and I want to give a small slice of it to some friends. With multiple people doing the same, we get a simple storage network for cheap offsite backups.
The server is a Raspberry Pi, the drive is a 4TB WD USB disk.
Requirements
- A large BTRFS formatted volume, mounted on
/mnt/big
- Logged in as root,
cd /mnt/big
- I want to create a new user, “foo”, with homedirectory
/home/foo
stored on the big drive, with an artificial disk quota of 1TB.
Steps
Enable quota on the disk:
btrfs quota enable .
Create a subvolume:
btrfs subvolume create foo
You have a directory “foo” that is also a subvolume. Set its quota:
btrfs qgroup limit 1T foo
Create the new user:
useradd -m foo chown foo:foo /mnt/big/foo chmod 700 /mnt/big/foo
Bonus: move all skeleton created files from the new home directory to the subvolume:
find /home/foo -mindepth 1 -maxdepth 1 -exec mv {} ./foo/ ";"
There are probably better ways to do that but this worked for me.
I make the unmounted home directory inaccessible to the new user so it fails loudly when I forget to mount the btrfs subvolume (e.g. after restart):
sudo chown root:root /home/foo
These permissions will get reset to foo:foo automatically on mount
Make sure your btrfs drive has a label:
btrfs filesystem label .
If that doesn’t return anything, set one:
btrfs filesystem label . my_btrfs_drive
Now mount the subvolume as the user’s homedir by adding this to /etc/fstab
:
LABEL=my_btrfs_drive /home/foo btrfs subvol=/foo,noatime 0 0
And mount everything:
mount -a
Done! You now have a user “foo” with a home directory mounted from a btrfs subvolume, with a quota of 1TB on their subvolume (i.e. home directory). You can take snapshots of this subvolume at will.
To see disk usage of all subvolumes of your entire btrfs drive:
btrfs qgroup show .
qgroupid rfer excl -------- ---- ---- 0/5 757.68GiB 224.48GiB 0/1013 0.00B 0.00B 0/1017 607.32GiB 74.11GiB 0/1018 20.00KiB 20.00KiB
The rfer
column is total disk size, the excl
column is for data that is unique to that volume.
To see quota usage for a subvolume:
btrfs qgroup show -reF foo
qgroupid rfer excl max_rfer max_excl -------- ---- ---- -------- -------- 0/1017 607.32GiB 74.11GiB 2.00TiB none
Same as above, but it tells you exactly what the limits are.