| #! /bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # Copyright (c) 2025 Oracle. All Rights Reserved. |
| # |
| # FS QA Test No. 767 |
| # |
| # Validate multi-fsblock atomic write support with simulated hardware support |
| # |
| . ./common/preamble |
| _begin_fstest auto quick rw atomicwrites |
| |
| . ./common/scsi_debug |
| . ./common/atomicwrites |
| |
| _cleanup() |
| { |
| _scratch_unmount &>/dev/null |
| _put_scsi_debug_dev &>/dev/null |
| cd / |
| rm -r -f $tmp.* |
| } |
| |
| _require_scsi_debug |
| _require_scratch |
| _require_block_device $SCRATCH_DEV |
| _require_xfs_io_command "falloc" |
| |
| # Format something so that ./check doesn't freak out |
| _scratch_mkfs >> $seqres.full |
| |
| # 512b logical/physical sectors, 512M size, atomic writes enabled |
| dev=$(_get_scsi_debug_dev 512 512 0 512 "atomic_wr=1") |
| test -b "$dev" || _notrun "could not create atomic writes scsi_debug device" |
| |
| export SCRATCH_DEV=$dev |
| unset USE_EXTERNAL |
| |
| _require_scratch_write_atomic |
| |
| # Check that xfs_io supports the commands needed to run this test |
| # Note: _require_xfs_io_command is not used here because we want to |
| # run this test even if $TEST_DIR does not support atomic writes |
| $XFS_IO_PROG -c 'help pwrite' | grep -q RWF_ATOMIC || _notrun "xfs_io pwrite -A failed" |
| $XFS_IO_PROG -c 'help falloc' | grep -q 'not found' && _notrun "xfs_io falloc failed" |
| $XFS_IO_PROG -c 'help statx' | grep -q -- '-r' || _notrun "xfs_io statx -r failed" |
| |
| echo "scsi_debug atomic write properties" >> $seqres.full |
| $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full |
| |
| _scratch_mkfs >> $seqres.full |
| _scratch_mount |
| test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT |
| |
| testfile=$SCRATCH_MNT/testfile |
| touch $testfile |
| |
| echo "filesystem atomic write properties" >> $seqres.full |
| $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full |
| |
| sector_size=$(blockdev --getss $SCRATCH_DEV) |
| min_awu=$(_get_atomic_write_unit_min $testfile) |
| max_awu=$(_get_atomic_write_unit_max $testfile) |
| opt_awu=$(_get_atomic_write_unit_max_opt $testfile) |
| |
| echo "min:$min_awu max:$max_awu opt:$opt_awu" >> $seqres.full |
| |
| # We want to test hardware support, so use that if detected |
| if [ -n "$opt_awu" ] && [ "$opt_awu" != "0" ]; then |
| write_size="$opt_awu" |
| else |
| write_size="$max_awu" |
| fi |
| |
| $XFS_IO_PROG -f -c "falloc 0 $((write_size * 2))" -c fsync $testfile |
| |
| # try outside the advertised sizes |
| echo "two EINVAL for unsupported sizes" |
| min_i=$((min_awu / 2)) |
| _simple_atomic_write $min_i $min_i $testfile -d |
| max_i=$((max_awu * 2)) |
| _simple_atomic_write $max_i $max_i $testfile -d |
| |
| # try all of the advertised sizes |
| echo "all should work" |
| for ((i = min_awu; i <= write_size; i *= 2)); do |
| $XFS_IO_PROG -f -c "falloc 0 $((write_size * 2))" -c fsync $testfile |
| _test_atomic_file_writes $i $testfile |
| done |
| |
| # does not support buffered io |
| echo "one EOPNOTSUPP for buffered atomic" |
| _simple_atomic_write 0 $min_awu $testfile |
| |
| # does not support unaligned directio |
| echo "one EINVAL for unaligned directio" |
| _simple_atomic_write $sector_size $min_awu $testfile -d |
| |
| _scratch_unmount |
| _put_scsi_debug_dev |
| |
| # success, all done |
| echo Silence is golden |
| status=0 |
| exit |