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. --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 >