On Tue, Apr 16, 2024 at 11:54:37AM -0700, Darrick J. Wong wrote: > On Tue, Apr 16, 2024 at 09:07:43AM +0000, Hans Holmberg wrote: > > +Zorro (doh!) > > > > On 2024-04-15 13:23, Hans Holmberg wrote: > > > This test stresses garbage collection for file systems by first filling > > > up a scratch mount to a specific usage point with files of random size, > > > then doing overwrites in parallel with deletes to fragment the backing > > > storage, forcing reclaim. > > > > > > Signed-off-by: Hans Holmberg <hans.holmberg@xxxxxxx> > > > --- > > > > > > Test results in my setup (kernel 6.8.0-rc4+) > > > f2fs on zoned nullblk: pass (77s) > > > f2fs on conventional nvme ssd: pass (13s) > > > btrfs on zoned nublk: fails (-ENOSPC) > > > btrfs on conventional nvme ssd: fails (-ENOSPC) > > > xfs on conventional nvme ssd: pass (8s) > > > > > > Johannes(cc) is working on the btrfs ENOSPC issue. > > > > > > tests/generic/744 | 124 ++++++++++++++++++++++++++++++++++++++++++ > > > tests/generic/744.out | 6 ++ > > > 2 files changed, 130 insertions(+) > > > create mode 100755 tests/generic/744 > > > create mode 100644 tests/generic/744.out > > > > > > diff --git a/tests/generic/744 b/tests/generic/744 > > > new file mode 100755 > > > index 000000000000..2c7ab76bf8b1 > > > --- /dev/null > > > +++ b/tests/generic/744 > > > @@ -0,0 +1,124 @@ > > > +#! /bin/bash > > > +# SPDX-License-Identifier: GPL-2.0 > > > +# Copyright (c) 2024 Western Digital Corporation. All Rights Reserved. > > > +# > > > +# FS QA Test No. 744 > > > +# > > > +# Inspired by btrfs/273 and generic/015 > > > +# > > > +# This test stresses garbage collection in file systems > > > +# by first filling up a scratch mount to a specific usage point with > > > +# files of random size, then doing overwrites in parallel with > > > +# deletes to fragment the backing zones, forcing reclaim. > > > + > > > +. ./common/preamble > > > +_begin_fstest auto > > > + > > > +# real QA test starts here > > > + > > > +_require_scratch > > > + > > > +# This test requires specific data space usage, skip if we have compression > > > +# enabled. > > > +_require_no_compress > > > + > > > +M=$((1024 * 1024)) > > > +min_fsz=$((1 * ${M})) > > > +max_fsz=$((256 * ${M})) > > > +bs=${M} > > > +fill_percent=95 > > > +overwrite_percentage=20 > > > +seq=0 > > > + > > > +_create_file() { > > > + local file_name=${SCRATCH_MNT}/data_$1 > > > + local file_sz=$2 > > > + local dd_extra=$3 > > > + > > > + POSIXLY_CORRECT=yes dd if=/dev/zero of=${file_name} \ > > > + bs=${bs} count=$(( $file_sz / ${bs} )) \ > > > + status=none $dd_extra 2>&1 > > > + > > > + status=$? > > > + if [ $status -ne 0 ]; then > > > + echo "Failed writing $file_name" >>$seqres.full > > > + exit > > > + fi > > > +} > > I wonder, is there a particular reason for doing all these file > operations with shell code instead of using fsstress to create and > delete files to fill the fs and stress all the zone-gc code? This test > reminds me a lot of generic/476 but with more fork()ing. /me has the same confusion. Can this test cover more things than using fsstress (to do reclaim test) ? Or does it uncover some known bugs which other cases can't? Thanks, Zorro > > --D > > > > + > > > +_total_M() { > > > + local total=$(stat -f -c '%b' ${SCRATCH_MNT}) > > > + local bs=$(stat -f -c '%S' ${SCRATCH_MNT}) > > > + echo $(( ${total} * ${bs} / ${M})) > > > +} > > > + > > > +_used_percent() { > > > + local available=$(stat -f -c '%a' ${SCRATCH_MNT}) > > > + local total=$(stat -f -c '%b' ${SCRATCH_MNT}) > > > + echo $((100 - (100 * ${available}) / ${total} )) > > > +} > > > + > > > + > > > +_delete_random_file() { > > > + local to_delete=$(find ${SCRATCH_MNT} -type f | shuf | head -1) > > > + rm $to_delete > > > + sync ${SCRATCH_MNT} > > > +} > > > + > > > +_get_random_fsz() { > > > + local r=$RANDOM > > > + echo $(( ${min_fsz} + (${max_fsz} - ${min_fsz}) * (${r} % 100) / 100 )) > > > +} > > > + > > > +_direct_fillup () { > > > + while [ $(_used_percent) -lt $fill_percent ]; do > > > + local fsz=$(_get_random_fsz) > > > + > > > + _create_file $seq $fsz "oflag=direct conv=fsync" > > > + seq=$((${seq} + 1)) > > > + done > > > +} > > > + > > > +_mixed_write_delete() { > > > + local dd_extra=$1 > > > + local total_M=$(_total_M) > > > + local to_write_M=$(( ${overwrite_percentage} * ${total_M} / 100 )) > > > + local written_M=0 > > > + > > > + while [ $written_M -lt $to_write_M ]; do > > > + if [ $(_used_percent) -lt $fill_percent ]; then > > > + local fsz=$(_get_random_fsz) > > > + > > > + _create_file $seq $fsz "$dd_extra" > > > + written_M=$((${written_M} + ${fsz}/${M})) > > > + seq=$((${seq} + 1)) > > > + else > > > + _delete_random_file > > > + fi > > > + done > > > +} > > > + > > > +seed=$RANDOM > > > +RANDOM=$seed > > > +echo "Running test with seed=$seed" >>$seqres.full > > > + > > > +_scratch_mkfs_sized $((8 * 1024 * 1024 * 1024)) >>$seqres.full > > > +_scratch_mount > > > + > > > +echo "Starting fillup using direct IO" > > > +_direct_fillup > > > + > > > +echo "Starting mixed write/delete test using direct IO" > > > +_mixed_write_delete "oflag=direct" > > > + > > > +echo "Starting mixed write/delete test using buffered IO" > > > +_mixed_write_delete "" > > > + > > > +echo "Syncing" > > > +sync ${SCRATCH_MNT}/* > > > + > > > +echo "Done, all good" > > > + > > > +# success, all done > > > +status=0 > > > +exit > > > diff --git a/tests/generic/744.out b/tests/generic/744.out > > > new file mode 100644 > > > index 000000000000..b40c2f43108e > > > --- /dev/null > > > +++ b/tests/generic/744.out > > > @@ -0,0 +1,6 @@ > > > +QA output created by 744 > > > +Starting fillup using direct IO > > > +Starting mixed write/delete test using direct IO > > > +Starting mixed write/delete test using buffered IO > > > +Syncing > > > +Done, all good > > >