#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2024 Christoph Hellwig.
#
# FS QA Test No. 643
#
# Test that GC defragments sequentially written files.
#
. ./common/preamble
_begin_fstest auto rw zone

. ./common/filter
. ./common/zoned

_require_scratch
_require_odirect
_require_aio

_scratch_mkfs_sized $((256 * 1024 * 1024))  >>$seqres.full 2>&1

# limit to two max open zones so that all writes get thrown into the blender
export MOUNT_OPTIONS="$MOUNT_OPTIONS -o max_open_zones=2"
_try_scratch_mount || _notrun "mount option not supported"
_require_xfs_scratch_zoned

fio_config=$tmp.fio
fio_out=$tmp.fio.out
fio_err=$tmp.fio.err

cat >$fio_config <<EOF
[global]
bs=64k
iodepth=16
iodepth_batch=8
directory=$SCRATCH_MNT
ioengine=libaio
rw=write
direct=1
size=30m

[file1]
filename=file1

[file2]
filename=file2

[file3]
filename=file3

[file4]
filename=file4

[file5]
filename=file5

[file6]
filename=file6

[file7]
filename=file7

[file8]
filename=file8
EOF

_require_fio $fio_config

# create fragmented files
$FIO_PROG $fio_config --output=$fio_out
cat $fio_out >> $seqres.full

# fill up all remaining user capacity
dd if=/dev/zero of=$SCRATCH_MNT/fill bs=4k >> $seqres.full 2>&1

sync

# all files should be badly fragmented now
extents2=$(_count_extents $SCRATCH_MNT/file2)
echo "number of file 2 extents: $extents2" >>$seqres.full
test $extents2 -gt 200 || _fail "fio did not fragment file"

extents4=$(_count_extents $SCRATCH_MNT/file4)
echo "number of file 4 extents: $extents4" >>$seqres.full
test $extents4 -gt 200 || _fail "fio did not fragment file"

extents6=$(_count_extents $SCRATCH_MNT/file6)
echo "number of file 6 extents: $extents6" >>$seqres.full
test $extents6 -gt 200 || _fail "fio did not fragment file"

extents8=$(_count_extents $SCRATCH_MNT/file8)
echo "number of file 8 extents: $extents8" >>$seqres.full
test $extents8 -gt 200 || _fail "fio did not fragment file"

# remove half of the files to create work for GC
rm $SCRATCH_MNT/file1
rm $SCRATCH_MNT/file3
rm $SCRATCH_MNT/file5
rm $SCRATCH_MNT/file7

# fill up all remaining user capacity a few times to force GC
for i in `seq 1 10`; do
	dd if=/dev/zero of=$SCRATCH_MNT/fill bs=4k >> $seqres.full 2>&1
	$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/fill >> $seqres.full 2>&1
done

#
# All files should have a no more than a handful of extents now
#
extents2=$(_count_extents $SCRATCH_MNT/file2)
_within_tolerance "file 2 extents" $extents2 3 2 -v
extents4=$(_count_extents $SCRATCH_MNT/file4)
_within_tolerance "file 4 extents" $extents4 3 2 -v
extents6=$(_count_extents $SCRATCH_MNT/file6)
_within_tolerance "file 6 extents" $extents6 3 2 -v
extents8=$(_count_extents $SCRATCH_MNT/file8)
_within_tolerance "file 8 extents" $extents8 3 2 -v

status=0
exit
