#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2025 IBM Corporation. All Rights Reserved.
#
# FS QA Test No. 774
#
# Validate FS atomic write using fio crc check verifier on mixed mappings
# of a file.
#
. ./common/preamble
. ./common/atomicwrites

_begin_fstest auto aio rw atomicwrites

_require_scratch_write_atomic_multi_fsblock
_require_odirect
_require_aio
_require_fio_atomic_writes
_require_xfs_io_command "truncate"

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

touch "$SCRATCH_MNT/f1"
awu_min_write=$(_get_atomic_write_unit_min "$SCRATCH_MNT/f1")
awu_max_write=$(_get_atomic_write_unit_max "$SCRATCH_MNT/f1")

aw_bsize=$(_max "$awu_min_write" "$((awu_max_write/4))")
fsbsize=$(_get_block_size $SCRATCH_MNT)

threads=$(_min "$(($(nproc) * 2 * LOAD_FACTOR))" "100")
filesize=$((aw_bsize * threads * 100))
depth=$threads
aw_io_size=$((filesize / threads))
aw_io_inc=$aw_io_size
testfile=$SCRATCH_MNT/test-file

fio_prep_config=$tmp.prep.fio
fio_aw_config=$tmp.aw.fio
fio_verify_config=$tmp.verify.fio
fio_out=$tmp.fio.out

cat >$fio_prep_config <<EOF
# prep file to have mixed mappings
[global]
ioengine=libaio
filename=$testfile
size=$filesize
bs=$fsbsize
direct=1
iodepth=$depth
group_reporting=1

# Create written extents
[prep_written_blocks]
ioengine=libaio
rw=randwrite
io_size=$((filesize/3))
random_generator=lfsr

# Create unwritten extents
[prep_unwritten_blocks]
ioengine=falloc
rw=randwrite
io_size=$((filesize/3))
random_generator=lfsr
EOF

cat >$fio_aw_config <<EOF
# atomic write to mixed mappings of written/unwritten/holes
[atomic_write_job]
ioengine=libaio
rw=randwrite
direct=1
atomic=1
random_generator=lfsr
group_reporting=1

filename=$testfile
bs=$aw_bsize
size=$aw_io_size
offset_increment=$aw_io_inc
iodepth=$depth
numjobs=$threads

verify_state_save=0
verify=crc32c
do_verify=0
EOF

cat >$fio_verify_config <<EOF
# verify atomic writes done by previous job
[verify_job]
ioengine=libaio
rw=read
random_generator=lfsr
group_reporting=1

filename=$testfile
size=$filesize
bs=$aw_bsize
iodepth=$depth

verify_state_save=0
verify_only=1
verify=crc32c
verify_fatal=1
verify_write_sequence=0
EOF

_require_fio $fio_aw_config
_require_fio $fio_verify_config

cat $fio_prep_config >> $seqres.full
cat $fio_aw_config >> $seqres.full
cat $fio_verify_config >> $seqres.full

$XFS_IO_PROG -fc "truncate $filesize" $testfile >> $seqres.full

#prepare file with mixed mappings
$FIO_PROG $fio_prep_config >> $seqres.full

# do atomic writes without verifying
$FIO_PROG $fio_aw_config >> $seqres.full

# verify data is not torn
$FIO_PROG $fio_verify_config >> $seqres.full

# success, all done
echo Silence is golden
status=0
exit
