path: root/tests
diff options
authorFilipe Manana <>2015-07-16 16:47:13 +0100
committerDavid Sterba <>2015-08-31 19:25:03 +0200
commita57606e815f3e1c4fe66c61ce3c6e3621ea522e9 (patch)
treec080653dec7deef76a04045c57ee170a8b091aae /tests
parent9dbee1a6802896a6443896bfe407ab4062dff4f9 (diff)
Btrfs-progs: add feature to get mininum size for resizing a fs/device
Currently there is not way for a user to know what is the minimum size a device of a btrfs filesystem can be resized to. Sometimes the value of total allocated space (sum of all allocated chunks/device extents), which can be parsed from 'btrfs filesystem show' and 'btrfs filesystem usage', works as the minimum size, but sometimes it does not, namely when device extents have to relocated to holes (unallocated space) within the new size of the device (the total allocated space sum). This change adds the ability to reliably compute such minimum value and extents 'btrfs filesystem resize' with the following syntax to get such value: btrfs filesystem resize [devid:]get_min_size Signed-off-by: Filipe Manana <> Signed-off-by: David Sterba <>
Diffstat (limited to 'tests')
2 files changed, 71 insertions, 0 deletions
diff --git a/tests/ b/tests/
index 5bbe9140..2ae99db9 100755
--- a/tests/
+++ b/tests/
@@ -20,6 +20,8 @@ export RESULTS
# For custom script needs to verfiy recovery
export TEST_MNT
export LANG
+# For tests that only use a loop device
+export IMAGE
rm -f $RESULTS
mkdir -p $TEST_MNT || _fail "unable to create mount point on $TEST_MNT"
diff --git a/tests/misc-tests/004-shrink-fs/ b/tests/misc-tests/004-shrink-fs/
new file mode 100755
index 00000000..393cccf5
--- /dev/null
+++ b/tests/misc-tests/004-shrink-fs/
@@ -0,0 +1,69 @@
+# Test getting the minimum size a filesystem can be resized to and verify we
+# are able to resize (shrink) it to that size.
+source $TOP/tests/common
+check_prereq mkfs.btrfs
+ min_size=$($SUDO_HELPER $TOP/btrfs filesystem resize get_min_size $TEST_MNT)
+ if [ $? != 0 ]; then
+ _fail "Failed to get minimum size"
+ fi
+ min_size=$(echo $min_size | cut -d ' ' -f 1)
+ echo "min size = ${min_size}" >> $RESULTS
+ run_check $SUDO_HELPER $TOP/btrfs filesystem resize $min_size $TEST_MNT
+run_check truncate -s 20G $IMAGE
+run_check $TOP/mkfs.btrfs -f $IMAGE
+run_check $SUDO_HELPER mount $IMAGE $TEST_MNT
+run_check $SUDO_HELPER chmod a+rw $TEST_MNT
+# Create 7 data block groups, each with a size of 1Gb.
+for ((i = 1; i <= 7; i++)); do
+ run_check fallocate -l 1G $TEST_MNT/foo$i
+# Make sure they are persisted (all the chunk, device and block group items
+# added to the chunk/dev/extent trees).
+run_check $TOP/btrfs filesystem sync $TEST_MNT
+# Now remove 3 of those 1G files. This will result in 3 block groups becoming
+# unused, which will be automatically deleted by the cleaner kthread, and this
+# will result in 3 holes (unallocated space) in the device (each with a size
+# of 1Gb).
+run_check rm -f $TEST_MNT/foo2
+run_check rm -f $TEST_MNT/foo4
+run_check rm -f $TEST_MNT/foo6
+# Sync once to wake up the cleaner kthread which will delete the unused block
+# groups - it could have been sleeping when they became unused. Then wait a bit
+# to allow the cleaner kthread to delete them and then finally ensure the
+# transaction started by the cleaner kthread is committed.
+run_check $TOP/btrfs filesystem sync $TEST_MNT
+sleep 3
+run_check $TOP/btrfs filesystem sync $TEST_MNT
+# Now attempt to get the minimum size we can resize the filesystem to and verify
+# the resize operation succeeds. This size closely matches the sum of the size
+# of all the allocated device extents.
+for ((i = 1; i <= 3; i++)); do
+ shrink_test
+# Now convert metadata and system chunks to the single profile and check we are
+# still able to get a correct minimum size and shrink to that size.
+run_check $SUDO_HELPER $TOP/btrfs balance start -mconvert=single \
+ -sconvert=single -f $TEST_MNT
+for ((i = 1; i <= 3; i++)); do
+ shrink_test
+run_check $SUDO_HELPER umount $TEST_MNT