Skip to content

Instantly share code, notes, and snippets.

@gwpl
Last active December 15, 2017 19:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gwpl/c36483d8ccc6af31cf8e561899ae2da5 to your computer and use it in GitHub Desktop.
Save gwpl/c36483d8ccc6af31cf8e561899ae2da5 to your computer and use it in GitHub Desktop.
2017-12-14 Playing with BTRFS quota limits - Grzegorz Wierzowiecki
#!/bin/bash
# 2017-12-14 Playing with BTRFS quota limits - Grzegorz Wierzowiecki
# gist:
# Below script is prepared for easy experimentation, and should run copy-and-paste
# (you need permissions to create lvm groups, etc. therefore root)
# It
# * setup 128MiB btrfstest in selected volume group
# * setup quotas (32MiB and 64MiB) and test them
# * cleanup
# Helpful references:
# https://wiki.archlinux.org/index.php/Btrfs
# https://btrfs.wiki.kernel.org/index.php/Quota_support
# https://serverfault.com/a/803702/65137
# https://gist.github.com/mazgi/d7317aa1959ca4434ab1
# https://btrfs.wiki.kernel.org/index.php/UseCases#How_do_we_implement_quota_in_BTRFS.3F
# input parameters
read -p 'Provide your LVM volume group:' vgname
# rest of script should be fully automatic ready for copy&paste
lvname=btrfstest
# create 128m lvm volume for this test
lvcreate -L 128m -n "${lvname?}" "${vgname?}"
lvpath=/dev/mapper/"${vgname?}-${lvname?}"
# make it btrfs
mkfs.btrfs -L "${lvname?}" "${lvpath?}"
# mount it
mntpath="$(mktemp -d --suffix="_$lvname")"
mount -t btrfs "${lvpath?}" "${mntpath?}"
# check it's size
df -h "$mntpath"
# create subvolumes subA and subB
btrfs subvolume create "${mntpath?}"/subA
btrfs subvolume create "${mntpath?}"/subB
# list subvolumes
btrfs subvolume list "${mntpath?}"
# example output:
# > ID 256 gen 8 top level 5 path subA
# > ID 257 gen 9 top level 5 path subB
#
# Try to enable quotas
btrfs quota enable "${mntpath?}"
btrfs quota rescan "${mntpath?}"
# Now execute:
btrfs subvolume list "${mntpath?}" | cut -d' ' -f2 | xargs -I{} -n1 btrfs qgroup create 0/{} "${mntpath?}"
# effectively executing in case of above IDs:
# btrfs qgroup create 0/256 "${mntpath?}"
# btrfs qgroup create 0/257 "${mntpath?}"
btrfs qgroup show "${mntpath?}"
# in our case may output:
# > qgroupid rfer excl
# > -------- ---- ----
# > 0/5 16.00KiB 16.00KiB
# > 0/256 0.00B 0.00B
# > 0/257 0.00B 0.00B
#
# So, let's run rescan, wait a bit and try show again, more detailed
btrfs quota rescan "${mntpath?}"
btrfs qgroup show -perc "${mntpath?}"
# no it outputs:
# > qgroupid rfer excl max_rfer max_excl parent child
# > -------- ---- ---- -------- -------- ------ -----
# > 0/5 16.00KiB 16.00KiB none none --- ---
# > 0/256 16.00KiB 16.00KiB none none --- ---
# > 0/257 16.00KiB 16.00KiB none none --- ---
#
# Let's apply limits:
# (according to https://btrfs.wiki.kernel.org/index.php/UseCases#How_do_we_implement_quota_in_BTRFS.3F )
btrfs qgroup limit 32M "${mntpath?}"/subA
btrfs qgroup limit 64M "${mntpath?}"/subB
btrfs qgroup show -perc "${mntpath?}"
# in our case:
# > qgroupid rfer excl max_rfer max_excl parent child
# > -------- ---- ---- -------- -------- ------ -----
# > 0/5 16.00KiB 16.00KiB none none --- ---
# > 0/256 16.00KiB 16.00KiB 32.00MiB none --- ---
# > 0/257 16.00KiB 16.00KiB 64.00MiB none --- ---
btrfs qgroup show -reF "${mntpath?}"
# output:
# > qgroupid rfer excl max_rfer max_excl
# > -------- ---- ---- -------- --------
# > 0/5 16.00KiB 16.00KiB none none
btrfs qgroup show -reF "${mntpath?}"/subA
# > qgroupid rfer excl max_rfer max_excl
# > -------- ---- ---- -------- --------
# > 0/256 16.00KiB 16.00KiB 32.00MiB none
btrfs qgroup show -reF "${mntpath?}"/subB
# > qgroupid rfer excl max_rfer max_excl
# > -------- ---- ---- -------- --------
# > 0/257 16.00KiB 16.00KiB 64.00MiB none
# Let's test it!
cat /dev/urandom > "${mntpath?}"/subA/file_with_urand
cat /dev/urandom > "${mntpath?}"/subB/file_with_urand
ls -lha "${mntpath?}"/sub{A,B}/file_with_urand
# > -rw-r--r-- 1 root root 32M Dec 15 19:51 /tmp/tmp.2AMRQgSfdP_btrfstest/subA/file_with_urand
# > -rw-r--r-- 1 root root 64M Dec 15 19:51 /tmp/tmp.2AMRQgSfdP_btrfstest/subB/file_with_urand
# Cleanup after tests:
umount "${mntpath?}"
rmdir "${mntpath?}"
lvremove -y "${lvpath?}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment