* [RFC 0/3] xfs: Add new xfs multi AG shrink tests
@ 2025-09-16 15:11 Nirjhar Roy (IBM)
2025-09-16 15:11 ` [RFC 1/3] xfs/163: Update this test with multi AG shrink sub-tests Nirjhar Roy (IBM)
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Nirjhar Roy (IBM) @ 2025-09-16 15:11 UTC (permalink / raw)
To: fstests
Cc: nirjhar.roy.lists, ritesh.list, ojaswin, djwong, bfoster, david,
hsiangkao, zlang
This patch series adds several multi AG shrink tests based on the RFC[1].
Patch 1/3 adds more basic shrink functionality tests to the already existing
ones in xfs/163.
Patch 2 adds tests that checks whether the filesystem is consistent
after several xfs_growfs operations(filesystem growth/shrink).
Patch 3 adds a test that repeatedly shrinks and shuts down the filesystem, thus
checking the log recovery correctness during multi AG shrink operations.
Tested them with 4k blocksize(on x86_64 with 4k page size) and 4k+64k blocksize
(on ppc64le with page size 64k).
[1] https://lore.kernel.org/all/cover.1758034274.git.nirjhar.roy.lists@gmail.com/
Nirjhar Roy (IBM) (3):
xfs/163: Update this test with multi AG shrink sub-tests
xfs: Add parallel back to back grow/shrink tests
xfs: Add multi AG shrink + shutdown + recovery tests
tests/xfs/163 | 162 ++++++++++++++++++++++++++++++++++++----------
tests/xfs/163.out | 23 +++++--
tests/xfs/333 | 87 +++++++++++++++++++++++++
tests/xfs/333.out | 2 +
tests/xfs/611 | 89 +++++++++++++++++++++++++
tests/xfs/611.out | 2 +
6 files changed, 327 insertions(+), 38 deletions(-)
create mode 100755 tests/xfs/333
create mode 100644 tests/xfs/333.out
create mode 100755 tests/xfs/611
create mode 100644 tests/xfs/611.out
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [RFC 1/3] xfs/163: Update this test with multi AG shrink sub-tests
2025-09-16 15:11 [RFC 0/3] xfs: Add new xfs multi AG shrink tests Nirjhar Roy (IBM)
@ 2025-09-16 15:11 ` Nirjhar Roy (IBM)
2025-09-16 15:11 ` [RFC 2/3] xfs: Add parallel back to back grow/shrink tests Nirjhar Roy (IBM)
2025-09-16 15:11 ` [RFC 3/3] xfs: Add multi AG shrink + shutdown + recovery tests Nirjhar Roy (IBM)
2 siblings, 0 replies; 4+ messages in thread
From: Nirjhar Roy (IBM) @ 2025-09-16 15:11 UTC (permalink / raw)
To: fstests
Cc: nirjhar.roy.lists, ritesh.list, ojaswin, djwong, bfoster, david,
hsiangkao, zlang
Now, that the support for removal of entire empty
AG has been added, add more sub-tests to validate
shrink sizes worth equal to or more than 1 AG along with
some out of bounds/invalid shrink sub-test cases.
Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
---
tests/xfs/163 | 162 ++++++++++++++++++++++++++++++++++++----------
tests/xfs/163.out | 23 +++++--
2 files changed, 147 insertions(+), 38 deletions(-)
diff --git a/tests/xfs/163 b/tests/xfs/163
index 015a82cd..fb80065f 100755
--- a/tests/xfs/163
+++ b/tests/xfs/163
@@ -6,14 +6,46 @@
#
# XFS shrinkfs basic functionality test
#
-# This test attempts to shrink with a small size (512K), half AG size and
-# an out-of-bound size (agsize + 1) to observe if it works as expected.
+# This test attempts to shrink the filesystem by various sizes and verifies
+# if it works as expected.
#
. ./common/preamble
_begin_fstest auto quick growfs shrinkfs
# Import common functions.
. ./common/filter
+_require_scratch_xfs_shrink
+
+AGCOUNT=16
+FSSIZE=$((2 * 1024 * 1024 * 1024)) # 2G
+_require_scratch_size $((FSSIZE / 1024))
+
+reset()
+{
+ _scratch_unmount >> $seqres.full 2>&1
+ # agcount in an xfs filesystem >= 2
+ _scratch_mkfs -dsize="$FSSIZE" -dagcount="$AGCOUNT" 2>&1 | \
+ tee -a $seqres.full | _filter_mkfs 2>$tmp.mkfs >/dev/null
+ . $tmp.mkfs
+ tot_dblocks=$dblocks
+ oagcount=$agcount
+ _scratch_mount >> $seqres.full
+}
+
+# This functions converts a given number of fsblocks to AG count.
+_dblocks_to_ag()
+{
+ local blocks="$1"
+ local agdiv=$((blocks/agsize))
+ local agmod=$((blocks%agsize))
+ local agc
+ if [[ "$agmod" == 0 ]]; then
+ agc="$agdiv"
+ else
+ agc=$(( agdiv + 1 ))
+ fi
+ echo "$agc"
+}
test_shrink()
{
@@ -24,47 +56,111 @@ test_shrink()
_check_scratch_fs
_scratch_mount
- # If we couldn't shrink the filesystem due to lack of space, we're
- # done with this test.
- [ $1 -ne $dblocks ] && \
- grep -q 'No space left on device' $tmp.growfs && \
- _notrun "Could not shrink due to lack of space"
cat $tmp.growfs >> $seqres.full
+ $XFS_INFO_PROG $SCRATCH_MNT 2>&1 | \
+ _filter_mkfs 2>$tmp.xfsinfo >/dev/null
+ . $tmp.xfsinfo
+ [ $ret -eq 0 ]
+}
+
+# run_test <number of blocks to remove> <test name> <optional: error message>
+# If the test is expected to succeed, then there is no need to provide an error
+# message.
+run_test_shrink()
+{
+ local delta_blocks="$1"
+ local test_name="$2"
+ local error_message="$3"
- $XFS_INFO_PROG $SCRATCH_MNT 2>&1 | _filter_mkfs 2>$tmp.growfs >/dev/null
- . $tmp.growfs
- [ $ret -eq 0 -a $1 -eq $dblocks ]
+ echo "$test_name"
+ reset
+ local tsize=$((tot_dblocks-delta_blocks))
+ local nagcount=`_dblocks_to_ag "$tsize"`
+ echo "delta = $delta_blocks newblocks = $tsize nagcount = $nagcount" \
+ >> $seqres.full
+ if [[ "$error_message" == "" ]]; then
+ # no error message means the test is expected to succeed
+ test_shrink "$tsize" || \
+ echo "Shrink $test_name failure"
+ # Verify the parameters
+ [[ "$dblocks" -ne "$tsize" ]] && \
+ echo "dblocks not changed properly after shrinking \"$test_name\"" \
+ && echo "expected $tsize got $dblocks"
+ [[ "$agcount" -ne "$nagcount" ]] && \
+ echo "agcount not changed properly after shrinking \"$test_name\"" \
+ && echo "expected $nagcount got $agcount"
+ else
+ test_shrink "$tsize" && \
+ echo "Shrink \"$test_name\" succeeded unexpectedly"
+ grep -q "$error_message" $tmp.growfs || \
+ echo "Error message missing - shrinking \"$test_name\" (expected: $error_message)"
+ # Verify the parameters
+ [[ "$dblocks" -ne "$tot_dblocks" ]] && \
+ echo "dblocks changed after shrink failure \"$test_name\"" && \
+ echo "expected $tot_dblocks got $dblocks"
+ [[ "$agcount" -ne "$oagcount" ]] && \
+ echo "agcount changed after shrink failure \"$test_name\"" && \
+ echo "expected $oagcount got $agcount"
+ fi
}
-_require_scratch_xfs_shrink
+# This function, first shrinks the fs, then grows it. This is to make sure that
+# the fs is able to grow properly after a shrink has taken place.
+# Usage: run_test_shrink_grow <number of blocks to remove> <test name>
+run_test_shrink_grow()
+{
+ local delta_blocks="$1"
+ local test_name="$2"
+
+ echo "$test_name"
+ reset
+ local tsize=$((tot_dblocks-delta_blocks))
+ test_shrink "$tsize" || \
+ echo "$test_name failure"
+ # Now grow the fs
+ test_shrink "$tot_dblocks" || \
+ echo "$test_name failure"
+ # Verify the parameters
+ [[ "$dblocks" -ne "$tot_dblocks" ]] && \
+ echo "dblocks not changed properly after \"$test_name\"" \
+ && echo "expected $tot_dblocks got $dblocks"
+ [[ "$agcount" -ne "$oagcount" ]] && \
+ echo "agcount not changed properly after \"$test_name\"" \
+ && echo "expected $oagcount got $agcount"
+}
-echo "Format and mount"
+reset
-# agcount = 1 is forbidden on purpose, and need to ensure shrinking to
-# 2 AGs isn't feasible yet. So agcount = 3 is the minimum number now.
-_scratch_mkfs -dsize="$((900 * 1024 * 1024))" -dagcount=3 2>&1 | \
- tee -a $seqres.full | _filter_mkfs 2>$tmp.mkfs >/dev/null
-. $tmp.mkfs
-t_dblocks=$dblocks
-_scratch_mount >> $seqres.full
+# Tests expected to pass
+# run_test_shrink <number of blocks to remove> <test name>
+echo "#Tests partial and multi-ag shrinking"
+run_test_shrink 1 "shrink by 1 block"
+run_test_shrink $((agsize/2)) "shrink by 0.5 AG"
+run_test_shrink $((agsize)) "shrink by 1 AG"
+run_test_shrink $((agsize*6)) "shrink by 6 AG"
+run_test_shrink $((agsize*3+agsize/2)) "shrink by 3.5 AG"
+echo
-echo "Shrink fs (small size)"
-test_shrink $((t_dblocks-512*1024/dbsize)) || \
- echo "Shrink fs (small size) failure"
+# run_test_shrink_grow <number of blocks to remove> <test name>
+echo "#Tests partial and multi-ag shink followed by growfs"
+run_test_shrink_grow $((agsize/2)) "shrink by 0.5 AG -> grow by 0.5 AG"
+run_test_shrink_grow $((agsize*6)) "shrink by 6 AG -> grow by 6 AG"
+run_test_shrink_grow $((agsize*3+agsize/2)) "shrink by 3.5 AG -> grow by 3.5 AG"
+echo
-echo "Shrink fs (half AG)"
-test_shrink $((t_dblocks-agsize/2)) || \
- echo "Shrink fs (half AG) failure"
+echo "#Test out of bounds ag shrink: Below tests are expected to fail"
+# Tests expected to fail
+# run_test_shrink_grow <number of blocks to remove> <test name> <error message>
+run_test_shrink "$(( (AGCOUNT - 1) * agsize ))" "shrink to 1 AG" "Invalid argument"
+run_test_shrink "$(( tot_dblocks - 1 ))" "shrink to 1 block" "Invalid argument"
-echo "Shrink fs (out-of-bound)"
-test_shrink $((t_dblocks-agsize-1)) && \
- echo "Shrink fs (out-of-bound) failure"
-[ $dblocks -ne $((t_dblocks-agsize/2)) ] && \
- echo "dblocks changed after shrinking failure"
+# XFS expects a minimum of XFS_MIN_AG_BLOCKS (64) per AG. If we are shrinking
+# the (new) tail AG below this threshold value, then the shrink op should fail.
+run_test_shrink "$(( agsize - 1 ))" "shrink tail AG to 1 block" "Invalid argument"
+run_test_shrink "$(( agsize * 2 - 1 ))" "shrink new tail AG to 1 block" "Invalid argument"
+echo
$XFS_INFO_PROG $SCRATCH_MNT >> $seqres.full
-echo "*** done"
# success, all done
-status=0
-exit
+_exit 0
diff --git a/tests/xfs/163.out b/tests/xfs/163.out
index bd66d4a9..4f15dc94 100644
--- a/tests/xfs/163.out
+++ b/tests/xfs/163.out
@@ -1,6 +1,19 @@
QA output created by 163
-Format and mount
-Shrink fs (small size)
-Shrink fs (half AG)
-Shrink fs (out-of-bound)
-*** done
+#Tests partial and multi-ag shrinking
+shrink by 1 block
+shrink by 0.5 AG
+shrink by 1 AG
+shrink by 6 AG
+shrink by 3.5 AG
+
+#Tests partial and multi-ag shink followed by growfs
+shrink by 0.5 AG -> grow by 0.5 AG
+shrink by 6 AG -> grow by 6 AG
+shrink by 3.5 AG -> grow by 3.5 AG
+
+#Test out of bounds ag shrink: Below tests are expected to fail
+shrink to 1 AG
+shrink to 1 block
+shrink tail AG to 1 block
+shrink new tail AG to 1 block
+
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [RFC 2/3] xfs: Add parallel back to back grow/shrink tests
2025-09-16 15:11 [RFC 0/3] xfs: Add new xfs multi AG shrink tests Nirjhar Roy (IBM)
2025-09-16 15:11 ` [RFC 1/3] xfs/163: Update this test with multi AG shrink sub-tests Nirjhar Roy (IBM)
@ 2025-09-16 15:11 ` Nirjhar Roy (IBM)
2025-09-16 15:11 ` [RFC 3/3] xfs: Add multi AG shrink + shutdown + recovery tests Nirjhar Roy (IBM)
2 siblings, 0 replies; 4+ messages in thread
From: Nirjhar Roy (IBM) @ 2025-09-16 15:11 UTC (permalink / raw)
To: fstests
Cc: nirjhar.roy.lists, ritesh.list, ojaswin, djwong, bfoster, david,
hsiangkao, zlang
This test makes several parallel back to back
shrink/grow requests and makes sure that at
the end of all operations, the filesystem is in
a consistent state with no corruptions and crashes.
Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
---
tests/xfs/611 | 89 +++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/611.out | 2 ++
2 files changed, 91 insertions(+)
create mode 100755 tests/xfs/611
create mode 100644 tests/xfs/611.out
diff --git a/tests/xfs/611 b/tests/xfs/611
new file mode 100755
index 00000000..605beddb
--- /dev/null
+++ b/tests/xfs/611
@@ -0,0 +1,89 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>. All Rights Reserved.
+#
+# FS QA Test 611
+#
+# This test is similar to xfs/163. It creates NUM_PROCS number of processes.
+# Some will pass, some will fail with
+# a) operation in progress
+# b) no space available
+# c) size unchanged.
+# The primary difference of this test with xfs/163 is that all the back to back
+# xfs_growfs requests are made without recreating the filesystem in between 2
+# requests. This test ensures that even after several grow/shrink requests, the
+# filesystem is in a consistent state and there are no crashes or metadata
+# corruptions.
+
+. ./common/preamble
+_begin_fstest auto quick growfs shrinkfs
+
+. ./common/filter
+_require_scratch_xfs_shrink
+
+AGCOUNT=16
+FSSIZE=$((2 * 1024 * 1024 * 1024)) # 2G
+NUM_LOOP=500
+NUM_PROCS=$((4 * LOAD_FACTOR))
+_require_scratch_size $((FSSIZE / 1024)) #KB
+
+_stress_scratch()
+{
+ procs=4
+ nops=9999
+ # -w ensures that the only ops are ones which cause write I/O
+ FSSTRESS_ARGS=`_scale_fsstress_args -d $SCRATCH_MNT -w -p $procs \
+ -n $nops`
+ _run_fsstress_bg $FSSTRESS_ARGS >> $seqres.full 2>&1
+}
+
+setup()
+{
+ _scratch_unmount >> $seqres.full 2>&1
+ # agcount in an xfs filesystem >= 2
+ _scratch_mkfs -dsize="$FSSIZE" -dagcount="$AGCOUNT" 2>&1 | \
+ tee -a $seqres.full | _filter_mkfs 2>$tmp.mkfs >/dev/null
+ . $tmp.mkfs
+ _scratch_mount >> $seqres.full
+}
+
+run_loop() {
+ for ((i=0; i<"$NUM_LOOP"; i++)); do
+ numag=$(( RANDOM % 17 ))
+ nblocksag=$(( numag * agsize ))
+ numblksoff=$(( RANDOM % agsize ))
+ nblkstot=$(( nblocksag + numblksoff ))
+ xfs_growfs -D "$nblkstot" $SCRATCH_MNT >> $seqres.full 2>&1
+ done
+}
+
+start_test()
+{
+ for ((j=0; j<"$NUM_PROCS"; j++)); do
+ run_loop "$j" &
+ done
+ if [[ "$1" -eq 1 ]]; then
+ _stress_scratch
+ fi
+}
+
+# We want to test with and without stress. The reason is that, if stress
+# fills up the filesystem such that all the AGs are non-empty, then all
+# the shrink commands will fail and we won't be able to test. So to cover all
+# the types of scenarios, we are testing with and without stress.
+for stress in 0 1
+do
+ setup
+ if [[ "$stress" -eq 1 ]]; then
+ echo "Testing with stress" >> $seqres.full 2>&1
+ else
+ echo "Testing without stress" >> $seqres.full 2>&1
+ fi
+ start_test "$stress"
+ wait
+ sleep 2
+ _check_scratch_fs
+done
+echo "Silence is golden"
+# success, all done
+_exit 0
diff --git a/tests/xfs/611.out b/tests/xfs/611.out
new file mode 100644
index 00000000..b8a44164
--- /dev/null
+++ b/tests/xfs/611.out
@@ -0,0 +1,2 @@
+QA output created by 611
+Silence is golden
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [RFC 3/3] xfs: Add multi AG shrink + shutdown + recovery tests
2025-09-16 15:11 [RFC 0/3] xfs: Add new xfs multi AG shrink tests Nirjhar Roy (IBM)
2025-09-16 15:11 ` [RFC 1/3] xfs/163: Update this test with multi AG shrink sub-tests Nirjhar Roy (IBM)
2025-09-16 15:11 ` [RFC 2/3] xfs: Add parallel back to back grow/shrink tests Nirjhar Roy (IBM)
@ 2025-09-16 15:11 ` Nirjhar Roy (IBM)
2 siblings, 0 replies; 4+ messages in thread
From: Nirjhar Roy (IBM) @ 2025-09-16 15:11 UTC (permalink / raw)
To: fstests
Cc: nirjhar.roy.lists, ritesh.list, ojaswin, djwong, bfoster, david,
hsiangkao, zlang
This test repeatedly shrinks, then shuts down
the filesystem and checks that recovery works
fine - this is similar to what is already being done
in xfs/609 but this tests with filesystem shrink and in
xfs/609 it is tested with filesystem growth.
Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
---
tests/xfs/333 | 87 +++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/333.out | 2 ++
2 files changed, 89 insertions(+)
create mode 100755 tests/xfs/333
create mode 100644 tests/xfs/333.out
diff --git a/tests/xfs/333 b/tests/xfs/333
new file mode 100755
index 00000000..1c319329
--- /dev/null
+++ b/tests/xfs/333
@@ -0,0 +1,87 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>. All Rights Reserved.
+#
+# FS QA Test 333
+#
+# Test XFS online growfs log recover with shrinking the filesystem
+#
+. ./common/preamble
+_begin_fstest auto growfs stress shutdown log recoveryloop shrinkfs
+
+# Import common functions.
+. ./common/filter
+
+_stress_scratch()
+{
+ procs=4
+ nops=999
+ # -w ensures that the only ops are ones which cause write I/O
+ FSSTRESS_ARGS=`_scale_fsstress_args -d $SCRATCH_MNT -w -p $procs \
+ -n $nops`
+ _run_fsstress_bg $FSSTRESS_ARGS >> $seqres.full 2>&1
+}
+FSSIZE=$(( 1024 * 1024 * 1024 )) # 1G
+_require_scratch
+_require_scratch_size $((FSSIZE / 1024)) #KB
+_require_command "$XFS_GROWFS_PROG" xfs_growfs
+
+_scratch_mkfs_xfs | _filter_mkfs >$seqres.full 2>$tmp.mkfs
+. $tmp.mkfs # extract blocksize and data size for scratch device
+
+endsize=`expr 128 \* 1048576` # stop after shrinking to this size
+[ `expr $endsize / $dbsize` -lt $dblocks ] || _notrun "Scratch device too small"
+
+nags=16
+# We want to test with and without stress. The reason is that, if stress
+# fills up the filesystem such that all the AGs are non-empty, then all
+# the shrink commands will fail and we won't be able to test recovery
+# during shrink. So to cover all the types of scenarios, we are testing
+# with and without stress.
+for stress in 0 1
+do
+ size=`expr 512 \* 1048576` # 512 megabytes initially
+ sizeb=`expr $size / $dbsize` # in data blocks
+ logblks=$(_scratch_find_xfs_min_logblocks -dsize=${size} -dagcount=${nags})
+ _scratch_mkfs_xfs -lsize=${logblks}b -dsize=${size} -dagcount=${nags} \
+ >> $seqres.full 2>&1 || _fail "mkfs failed"
+ _scratch_mount
+
+ $XFS_INFO_PROG $SCRATCH_MNT 2>&1 | _filter_mkfs 2>$tmp.xfsinfo >/dev/null
+ . $tmp.xfsinfo
+
+ if [[ "$stress" -eq 1 ]]; then
+ echo "Testing with Stress" >> $seqres.full 2>&1
+ else
+ echo "Testing without Stress" >> $seqres.full 2>&1
+ fi
+ # Shrink the filesystem in random sized chunks while performing shutdown and
+ # recovery. The randomization is intended to create a mix of sub-ag and
+ # multi-ag shrinks.
+ while [ $size -ge $endsize ]; do
+ echo "*** shrinking a ${sizeb} block filesystem (shrink)" >> \
+ $seqres.full
+ if [[ "$stress" -eq 1 ]]; then
+ _stress_scratch
+ fi
+
+ decsize=$((RANDOM % 40 * 1048576))
+ size=`expr $size - $decsize`
+ sizeb=`expr $size / $dbsize` # in data blocks
+ $XFS_GROWFS_PROG -D ${sizeb} $SCRATCH_MNT >> $seqres.full 2>&1
+
+ sleep $((RANDOM % 3))
+ _scratch_shutdown
+ if [[ "$stress" -eq 1 ]]; then
+ _kill_fsstress
+ fi
+ _scratch_cycle_mount
+ done > /dev/null 2>&1
+ wait
+ _scratch_unmount
+done
+
+echo "Silence is golden"
+
+_exit 0
+
diff --git a/tests/xfs/333.out b/tests/xfs/333.out
new file mode 100644
index 00000000..60a15898
--- /dev/null
+++ b/tests/xfs/333.out
@@ -0,0 +1,2 @@
+QA output created by 333
+Silence is golden
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-09-16 15:12 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-16 15:11 [RFC 0/3] xfs: Add new xfs multi AG shrink tests Nirjhar Roy (IBM)
2025-09-16 15:11 ` [RFC 1/3] xfs/163: Update this test with multi AG shrink sub-tests Nirjhar Roy (IBM)
2025-09-16 15:11 ` [RFC 2/3] xfs: Add parallel back to back grow/shrink tests Nirjhar Roy (IBM)
2025-09-16 15:11 ` [RFC 3/3] xfs: Add multi AG shrink + shutdown + recovery tests Nirjhar Roy (IBM)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox