blob: 8c4e0bd02e4e6570397f54158aae0249e2766c7c [file] [log] [blame]
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2025 Oracle. All Rights Reserved.
#
# FS QA Test 765
#
# Validate atomic write support
#
. ./common/preamble
_begin_fstest auto quick rw atomicwrites
. ./common/atomicwrites
_require_scratch_write_atomic
_require_atomic_write_test_commands
get_supported_bsize()
{
case "$FSTYP" in
"xfs")
min_bsize=1024
for ((i = 65536; i >= 1024; i /= 2)); do
_scratch_mkfs -b size=$i >> $seqres.full || continue
if _try_scratch_mount >> $seqres.full 2>&1; then
max_bsize=$i
_scratch_unmount
break;
fi
done
;;
"ext4")
min_bsize=1024
max_bsize=$(_get_page_size)
;;
*)
_notrun "$FSTYP does not support atomic writes"
;;
esac
echo "fs config ------------" >> $seqres.full
echo "min_bsize $min_bsize" >> $seqres.full
echo "max_bsize $max_bsize" >> $seqres.full
}
get_mkfs_opts()
{
local bsize=$1
case "$FSTYP" in
"xfs")
mkfs_opts="-b size=$bsize"
;;
"ext4")
mkfs_opts="-b $bsize"
;;
*)
_notrun "$FSTYP does not support atomic writes"
;;
esac
}
test_atomic_writes()
{
local bsize=$1
get_mkfs_opts $bsize
_scratch_mkfs $mkfs_opts >> $seqres.full
_scratch_mount
test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
testfile=$SCRATCH_MNT/testfile
touch $testfile
file_min_write=$(_get_atomic_write_unit_min $testfile)
file_max_write=$(_get_atomic_write_unit_max $testfile)
file_max_segments=$(_get_atomic_write_segments_max $testfile)
echo "test $bsize --------------" >> $seqres.full
echo "file awu_min $file_min_write" >> $seqres.full
echo "file awu_max $file_max_write" >> $seqres.full
echo "file awu_segments $file_max_segments" >> $seqres.full
# Check that atomic min/max = FS block size
test $file_min_write -eq $bsize || \
echo "atomic write min $file_min_write, should be fs block size $bsize"
test $file_max_write -ge $bsize || \
echo "atomic write max $file_max_write, should be at least fs block size $bsize"
test $file_max_segments -eq 1 || \
echo "atomic write max segments $file_max_segments, should be 1"
_test_atomic_file_writes "$bsize" "$testfile"
_scratch_unmount
}
sys_min_write=$(cat "/sys/block/$(_short_dev $SCRATCH_DEV)/queue/atomic_write_unit_min_bytes")
sys_max_write=$(cat "/sys/block/$(_short_dev $SCRATCH_DEV)/queue/atomic_write_unit_max_bytes")
bdev_min_write=$(_get_atomic_write_unit_min $SCRATCH_DEV)
bdev_max_write=$(_get_atomic_write_unit_max $SCRATCH_DEV)
echo "sysfs awu_min $sys_min_write" >> $seqres.full
echo "sysfs awu_min $sys_max_write" >> $seqres.full
echo "bdev awu_min $bdev_min_write" >> $seqres.full
echo "bdev awu_min $bdev_max_write" >> $seqres.full
# Test that statx atomic values are the same as sysfs values
if [ "$sys_min_write" -ne "$bdev_min_write" ]; then
echo "bdev min write != sys min write"
fi
if [ "$sys_max_write" -ne "$bdev_max_write" ]; then
echo "bdev max write != sys max write"
fi
get_supported_bsize
# Test all supported block sizes between bdev min and max
for ((bsize=$bdev_min_write; bsize<=bdev_max_write; bsize*=2)); do
if [ "$bsize" -ge "$min_bsize" ] && [ "$bsize" -le "$max_bsize" ]; then
test_atomic_writes $bsize
fi
done;
# success, all done
echo Silence is golden
status=0
exit