#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2019 Red Hat, Inc.  All Rights Reserved.
#
# FS QA Test No. 629
#
# Post-EOF preallocation defeat test for O_SYNC buffered I/O.
#

. ./common/preamble
_begin_fstest prealloc rw

. ./common/filter

_require_scratch
# _count_extents() needs the fiemap command
_require_xfs_io_command "fiemap"

_cleanup()
{
	# wait all background processes done
	wait
	cd /
	rm -r -f $tmp.*
}

_scratch_mkfs > "$seqres.full" 2>&1
_scratch_mount

# Write multiple files in parallel using synchronous buffered writes. Aim is to
# interleave allocations to fragment the files. Synchronous writes defeat the
# open/write/close heuristics in xfs_file_release() that prevent EOF block
# removal, so this should fragment badly. Typical problematic behaviour shows
# per-file extent counts of >900 (almost worse case) whilst fixed behaviour
# typically shows extent counts in the low 20s.
#
# Failure is determined by golden output mismatch from _within_tolerance().

workfile=$SCRATCH_MNT/file
nfiles=8
wsize=4096
wcnt=1000

write_sync_file()
{
	idx=$1

	for ((cnt=0; cnt<wcnt; cnt++)); do
		$XFS_IO_PROG -f -s -c "pwrite $((cnt * wsize)) $wsize" $workfile.$idx
	done
}

rm -f $workfile.*
for ((n=0; n<nfiles; n++)); do
	write_sync_file $n > /dev/null 2>&1 &
done
wait
_scratch_sync

for ((n=0; n<nfiles; n++)); do
	count=$(_count_extents $workfile.$n)
	# Acceptible extent count range is 1-41
	_within_tolerance "file.$n extent count" $count 21 20 -v
done

status=0
exit
