| #! /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 |