btrfs: add test for zone auto reclaim

Add a test for commit 18bb8bbf13c1 ("btrfs: zoned: automatically
reclaim zones").

This test creates a two file on a newly created FS in a way that
when we delete the first one, an auto reclaim process will be
triggered by the FS.

After the reclaim process, it verifies that the data was moved to
another zone and old zone was successfully reset.

Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
This commit is contained in:
Johannes Thumshirn
2021-04-29 21:39:27 +09:00
committed by Eryu Guan
parent a6dbebcb19
commit 0a095db5ef
4 changed files with 107 additions and 0 deletions
+1
View File
@@ -226,6 +226,7 @@ export FSVERITY_PROG="$(type -P fsverity)"
export OPENSSL_PROG="$(type -P openssl)"
export ACCTON_PROG="$(type -P accton)"
export E2IMAGE_PROG="$(type -P e2image)"
export BLKZONE_PROG="$(type -P blkzone)"
# use 'udevadm settle' or 'udevsettle' to wait for lv to be settled.
# newer systems have udevadm command but older systems like RHEL5 don't.
+103
View File
@@ -0,0 +1,103 @@
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2021 Western Digital Corporation. All Rights Reserved.
#
# FS QA Test 237
#
# Test that zone autoreclaim works as expected, that is: if the dirty
# threshold is exceeded the data gets relocated to new block group and the
# old block group gets deleted. On block group deletion, the underlying device
# zone also needs to be reset.
#
seq=`basename $0`
seqres=$RESULT_DIR/$seq
echo "QA output created by $seq"
here=`pwd`
tmp=/tmp/$$
status=1 # failure is the default!
trap "_cleanup; exit \$status" 0 1 2 3 15
_cleanup()
{
cd /
rm -f $tmp.*
}
# get standard environment, filters and checks
. ./common/rc
. ./common/filter
# remove previous $seqres.full before test
rm -f $seqres.full
# real QA test starts here
_supported_fs btrfs
_require_scratch
_require_btrfs_command inspect-internal dump-tree
_require_btrfs_command filesystem sync
_require_command "$BLKZONE_PROG" blkzone
_require_zoned_device "$SCRATCH_DEV"
get_data_bg()
{
$BTRFS_UTIL_PROG inspect-internal dump-tree -t CHUNK $SCRATCH_DEV |\
grep -A 1 "CHUNK_ITEM" | grep -B 1 "type DATA" |\
grep -Eo "CHUNK_ITEM [[:digit:]]+" | cut -d ' ' -f 2
}
zonesize=$(cat /sys/block/$(_short_dev $SCRATCH_DEV)/queue/chunk_sectors)
zonesize=$((zonesize << 9))
_scratch_mkfs >/dev/null 2>&1
_scratch_mount -o commit=1 # 1s commit time to speed up test
uuid=$(findmnt -n -o UUID "$SCRATCH_MNT")
reclaim_threshold=75
echo $reclaim_threshold > /sys/fs/btrfs/"$uuid"/bg_reclaim_threshold
fill_percent=$((reclaim_threshold + 2))
rest_percent=$((90 - fill_percent)) # make sure we're not creating a new BG
fill_size=$((zonesize * fill_percent / 100))
rest=$((zonesize * rest_percent / 100))
# step 1, fill FS over $fillsize
$XFS_IO_PROG -fc "pwrite 0 $fill_size" $SCRATCH_MNT/$seq.test1 >> $seqres.full
$XFS_IO_PROG -fc "pwrite 0 $rest" $SCRATCH_MNT/$seq.test2 >> $seqres.full
$BTRFS_UTIL_PROG filesystem sync $SCRATCH_MNT
zones_before=$($BLKZONE_PROG report $SCRATCH_DEV | grep -v -e em -e nw | wc -l)
echo "Before reclaim: $zones_before zones open" >> $seqres.full
old_data_zone=$(get_data_bg)
old_data_zone=$((old_data_zone >> 9))
printf "Old data zone 0x%x\n" $old_data_zone >> $seqres.full
# step 2, delete the 1st $fill_size sized file to trigger reclaim
rm $SCRATCH_MNT/$seq.test1
$BTRFS_UTIL_PROG filesystem sync $SCRATCH_MNT
sleep 2 # 1 transaction commit for 'rm' and 1 for balance
# check that we don't have more zones open than before
zones_after=$($BLKZONE_PROG report $SCRATCH_DEV | grep -v -e em -e nw | wc -l)
echo "After reclaim: $zones_after zones open" >> $seqres.full
# Check that old data zone was reset
old_wptr=$($BLKZONE_PROG report -o $old_data_zone -c 1 $SCRATCH_DEV |\
grep -Eo "wptr 0x[[:xdigit:]]+" | cut -d ' ' -f 2)
if [ "$old_wptr" != "0x000000" ]; then
_fail "Old wptr still at $old_wptr"
fi
new_data_zone=$(get_data_bg)
new_data_zone=$((new_data_zone >> 9))
printf "New data zone 0x%x\n" $new_data_zone >> $seqres.full
# Check that data was really relocated to a different zone
if [ $old_data_zone -eq $new_data_zone ]; then
echo "New zone same as old zone"
fi
# success, all done
echo "Silence is golden"
status=0
exit
+2
View File
@@ -0,0 +1,2 @@
QA output created by 237
Silence is golden
+1
View File
@@ -239,3 +239,4 @@
234 auto quick compress rw
235 auto quick send
236 auto quick log
237 auto quick zone balance