* [PATCH 1/4] common/scsi_debug: don't slow down I/O
2026-07-23 14:28 add tests for file system on devices using protection information Christoph Hellwig
@ 2026-07-23 14:28 ` Christoph Hellwig
2026-08-02 10:35 ` Zorro Lang
2026-07-23 14:28 ` [PATCH 2/4] common: add a _sysfs_block_integrity_path helper Christoph Hellwig
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Christoph Hellwig @ 2026-07-23 14:28 UTC (permalink / raw)
To: Zorro Lang
Cc: fstests, Martin K. Petersen, Kanchan Joshi, Anuj Gupta,
linux-scsi
scsi_debug by defaults delays I/O and doesn't support multi-page I/O.
Flipping these defaults speed up each test using scsi_debug by more than
an order of magnitute on my test systems.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
common/scsi_debug | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/common/scsi_debug b/common/scsi_debug
index c3fe7be623fa..91665547bc0c 100644
--- a/common/scsi_debug
+++ b/common/scsi_debug
@@ -59,7 +59,9 @@ _get_scsi_debug_dev()
let physical=physical/2
let phys_exp=phys_exp+1
done
- opts="sector_size=$logical physblk_exp=$phys_exp lowest_aligned=$unaligned dev_size_mb=$size $@"
+ opts="sector_size=$logical physblk_exp=$phys_exp"
+ opts="${opts} lowest_aligned=$unaligned dev_size_mb=$size"
+ opts="${opts} delay=0 clustering=1 $@"
echo "scsi_debug options $opts" >> $seqres.full
modprobe scsi_debug $opts
[ $? -eq 0 ] || _fail "scsi_debug modprobe failed"
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH 1/4] common/scsi_debug: don't slow down I/O
2026-07-23 14:28 ` [PATCH 1/4] common/scsi_debug: don't slow down I/O Christoph Hellwig
@ 2026-08-02 10:35 ` Zorro Lang
0 siblings, 0 replies; 7+ messages in thread
From: Zorro Lang @ 2026-08-02 10:35 UTC (permalink / raw)
To: Christoph Hellwig
Cc: fstests, Martin K. Petersen, Kanchan Joshi, Anuj Gupta,
linux-scsi
On Thu, Jul 23, 2026 at 04:28:44PM +0200, Christoph Hellwig wrote:
> scsi_debug by defaults delays I/O and doesn't support multi-page I/O.
> Flipping these defaults speed up each test using scsi_debug by more than
> an order of magnitute on my test systems.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> common/scsi_debug | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/common/scsi_debug b/common/scsi_debug
> index c3fe7be623fa..91665547bc0c 100644
> --- a/common/scsi_debug
> +++ b/common/scsi_debug
> @@ -59,7 +59,9 @@ _get_scsi_debug_dev()
> let physical=physical/2
> let phys_exp=phys_exp+1
> done
> - opts="sector_size=$logical physblk_exp=$phys_exp lowest_aligned=$unaligned dev_size_mb=$size $@"
> + opts="sector_size=$logical physblk_exp=$phys_exp"
> + opts="${opts} lowest_aligned=$unaligned dev_size_mb=$size"
> + opts="${opts} delay=0 clustering=1 $@"
> echo "scsi_debug options $opts" >> $seqres.full
> modprobe scsi_debug $opts
While this is syntactically correct, especially when leaving $opts unquoted.
But as this patch is trying to to improve code readability, so how about:
local opts=(
"sector_size=$logical"
"physblk_exp=$phys_exp"
"lowest_aligned=$unaligned"
"dev_size_mb=$size"
"delay=0"
"clustering=1"
)
opts+=("$@")
echo "scsi_debug options ${opts[*]}" >> $seqres.full
modprobe scsi_debug "${opts[@]}"
Thanks,
Zorro
> [ $? -eq 0 ] || _fail "scsi_debug modprobe failed"
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/4] common: add a _sysfs_block_integrity_path helper
2026-07-23 14:28 add tests for file system on devices using protection information Christoph Hellwig
2026-07-23 14:28 ` [PATCH 1/4] common/scsi_debug: don't slow down I/O Christoph Hellwig
@ 2026-07-23 14:28 ` Christoph Hellwig
2026-07-23 14:28 ` [PATCH 3/4] generic: test I/O on devices with T10 protection information Christoph Hellwig
2026-07-23 14:28 ` [PATCH 4/4] generic: test corruption detection using " Christoph Hellwig
3 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2026-07-23 14:28 UTC (permalink / raw)
To: Zorro Lang
Cc: fstests, Martin K. Petersen, Kanchan Joshi, Anuj Gupta,
linux-scsi
Add a helper function to find the sysfs integrity directory for a given
block device.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
common/rc | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/common/rc b/common/rc
index 106f044adc2d..96e74cfd4e5b 100644
--- a/common/rc
+++ b/common/rc
@@ -5254,6 +5254,31 @@ _sysfs_queue_path()
fi
}
+# Get the sysfs block device integrity/ path for a block device, handling
+# partitions correctly.
+_sysfs_block_integrity_path()
+{
+ local dev parent
+ dev=$(_short_dev "$1")
+
+ # For partitions, integrity details are in the parent device's sysfs dir
+ if [ -e "/sys/class/block/$dev/partition" ]; then
+ parent=$(basename "$(readlink -f /sys/class/block/$dev/..)")
+ else
+ parent="$dev"
+ fi
+
+ local integrity_path="/sys/block/$parent/integrity"
+
+ # Verify the path exists before returning
+ if [ -e "$integrity_path" ]; then
+ echo "$integrity_path"
+ return 0
+ fi
+
+ return 1
+}
+
# Get the minimum block size of a file. Usually this is the
# minimum fs block size, but some filesystems (ocfs2) do block
# mappings in larger units.
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/4] generic: test I/O on devices with T10 protection information
2026-07-23 14:28 add tests for file system on devices using protection information Christoph Hellwig
2026-07-23 14:28 ` [PATCH 1/4] common/scsi_debug: don't slow down I/O Christoph Hellwig
2026-07-23 14:28 ` [PATCH 2/4] common: add a _sysfs_block_integrity_path helper Christoph Hellwig
@ 2026-07-23 14:28 ` Christoph Hellwig
2026-07-23 14:28 ` [PATCH 4/4] generic: test corruption detection using " Christoph Hellwig
3 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2026-07-23 14:28 UTC (permalink / raw)
To: Zorro Lang
Cc: fstests, Martin K. Petersen, Kanchan Joshi, Anuj Gupta,
linux-scsi
Add a test that runs fsx in buffered and direct I/O mode on T10 PI
type 1, 2, 3 with and without strip/insert using scsi_debug.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
tests/generic/2301 | 90 ++++++++++++++++++++++++++++++++++++++++++
tests/generic/2301.out | 73 ++++++++++++++++++++++++++++++++++
2 files changed, 163 insertions(+)
create mode 100755 tests/generic/2301
create mode 100644 tests/generic/2301.out
diff --git a/tests/generic/2301 b/tests/generic/2301
new file mode 100755
index 000000000000..db984051430d
--- /dev/null
+++ b/tests/generic/2301
@@ -0,0 +1,90 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Christoph Hellwig
+#
+# FS QA Test No. 2301
+#
+# Basix FSX sanity check when using T10 protection information
+#
+. ./common/preamble
+_begin_fstest auto rw
+
+_cleanup()
+{
+ cd /
+ rm -r -f $tmp.*
+ [ -d "$SCSI_DEBUG_MNT" ] && _unmount $SCSI_DEBUG_MNT 2>/dev/null
+ _put_scsi_debug_dev
+}
+
+. ./common/scsi_debug
+
+_require_scsi_debug
+# If TEST_DEV is block device, make sure current fs is a localfs which can be
+# written on scsi_debug device
+_require_test
+_require_block_device $TEST_DEV
+
+size=$(_small_fs_size_mb 256)
+
+# like run_fsx(), but using a custom path
+fsx_run()
+{
+ _run_fsx_on_file $SCSI_DEBUG_MNT/junk $@ || _exit 1
+}
+
+test_dif()
+{
+ local pi_type=$1
+ local pi_enable="$2"
+
+ scsi_debug_pi_opts="write_same_length=0 dif=${pi_type} dix=1"
+ SCSI_DEBUG_DEV=`_get_scsi_debug_dev 512 512 0 $size $scsi_debug_pi_opts`
+
+ SCSI_DEBUG_MNT="$TEST_DIR/scsi_debug_$seq"
+ rm -rf $SCSI_DEBUG_MNT
+ mkdir $SCSI_DEBUG_MNT
+
+ _mkfs_dev $SCSI_DEBUG_DEV || \
+ _fail "Can't make $FSTYP on DIF-enabled scsi_debug device"
+ run_check _mount $SCSI_DEBUG_DEV $SCSI_DEBUG_MNT
+ bsize=$($here/src/min_dio_alignment $SCSI_DEBUG_MNT $SCSI_DEBUG_DEV)
+
+ local integrity_path="$(_sysfs_block_integrity_path $SCSI_DEBUG_DEV)"
+ echo $pi_enable > $integrity_path/read_verify
+ echo $pi_enable > $integrity_path/write_generate
+
+ # fsx load similar to generic/091
+ echo "Testing direct I/O for DIF type $pi_type (enabled: $pi_enable)"
+ local dio_opts="-r PSIZE -t BSIZE -w BSIZE"
+ fsx_run -N 10000 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+ fsx_run -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+ fsx_run -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+ fsx_run -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+ fsx_run -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+ fsx_run -N 10000 -o 128000 -l 500000 -r BSIZE -w BSIZE -Z -W
+
+ # fsx load similar to generic/091 but using buffered I/O
+ echo "Testing buffered I/O for DIF type $pi_type (enabled: $pi_enable)"
+ fsx_run -N 10000 -l 500000
+ fsx_run -N 10000 -o 8192 -l 500000
+ fsx_run -N 10000 -o 32768 -l 500000
+ fsx_run -N 10000 -o 128000 -l 500000
+
+ [ -d "$SCSI_DEBUG_MNT" ] && _unmount $SCSI_DEBUG_MNT 2>/dev/null
+ _put_scsi_debug_dev
+}
+
+# Test with PI fully enabled
+test_dif 1 1
+test_dif 2 1
+test_dif 3 1
+
+# Test with strip / insert in the HBA
+test_dif 1 0
+test_dif 2 0
+test_dif 3 0
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/2301.out b/tests/generic/2301.out
new file mode 100644
index 000000000000..dda88676a219
--- /dev/null
+++ b/tests/generic/2301.out
@@ -0,0 +1,73 @@
+QA output created by 2301
+Testing direct I/O for DIF type 1 (enabled: 1)
+fsx -N 10000 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 128000 -l 500000 -r BSIZE -w BSIZE -Z -W
+Testing buffered I/O for DIF type 1 (enabled: 1)
+fsx -N 10000 -l 500000
+fsx -N 10000 -o 8192 -l 500000
+fsx -N 10000 -o 32768 -l 500000
+fsx -N 10000 -o 128000 -l 500000
+Testing direct I/O for DIF type 2 (enabled: 1)
+fsx -N 10000 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 128000 -l 500000 -r BSIZE -w BSIZE -Z -W
+Testing buffered I/O for DIF type 2 (enabled: 1)
+fsx -N 10000 -l 500000
+fsx -N 10000 -o 8192 -l 500000
+fsx -N 10000 -o 32768 -l 500000
+fsx -N 10000 -o 128000 -l 500000
+Testing direct I/O for DIF type 3 (enabled: 1)
+fsx -N 10000 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 128000 -l 500000 -r BSIZE -w BSIZE -Z -W
+Testing buffered I/O for DIF type 3 (enabled: 1)
+fsx -N 10000 -l 500000
+fsx -N 10000 -o 8192 -l 500000
+fsx -N 10000 -o 32768 -l 500000
+fsx -N 10000 -o 128000 -l 500000
+Testing direct I/O for DIF type 1 (enabled: 0)
+fsx -N 10000 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 128000 -l 500000 -r BSIZE -w BSIZE -Z -W
+Testing buffered I/O for DIF type 1 (enabled: 0)
+fsx -N 10000 -l 500000
+fsx -N 10000 -o 8192 -l 500000
+fsx -N 10000 -o 32768 -l 500000
+fsx -N 10000 -o 128000 -l 500000
+Testing direct I/O for DIF type 2 (enabled: 0)
+fsx -N 10000 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 128000 -l 500000 -r BSIZE -w BSIZE -Z -W
+Testing buffered I/O for DIF type 2 (enabled: 0)
+fsx -N 10000 -l 500000
+fsx -N 10000 -o 8192 -l 500000
+fsx -N 10000 -o 32768 -l 500000
+fsx -N 10000 -o 128000 -l 500000
+Testing direct I/O for DIF type 3 (enabled: 0)
+fsx -N 10000 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 8192 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 32768 -l 500000 -r BSIZE -w BSIZE -Z -R -W
+fsx -N 10000 -o 128000 -l 500000 -r BSIZE -w BSIZE -Z -W
+Testing buffered I/O for DIF type 3 (enabled: 0)
+fsx -N 10000 -l 500000
+fsx -N 10000 -o 8192 -l 500000
+fsx -N 10000 -o 32768 -l 500000
+fsx -N 10000 -o 128000 -l 500000
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 4/4] generic: test corruption detection using T10 protection information
2026-07-23 14:28 add tests for file system on devices using protection information Christoph Hellwig
` (2 preceding siblings ...)
2026-07-23 14:28 ` [PATCH 3/4] generic: test I/O on devices with T10 protection information Christoph Hellwig
@ 2026-07-23 14:28 ` Christoph Hellwig
2026-08-02 11:57 ` Zorro Lang
3 siblings, 1 reply; 7+ messages in thread
From: Christoph Hellwig @ 2026-07-23 14:28 UTC (permalink / raw)
To: Zorro Lang
Cc: fstests, Martin K. Petersen, Kanchan Joshi, Anuj Gupta,
linux-scsi
Add a test that simulates bit flips in data and misdirected writes and
checks that file systems detect it when run on devices using protection
information.
This requires the new scsi_debug corruption injection.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
tests/generic/2302 | 143 +++++++++++++++++++++++++++++++++++++++++
tests/generic/2302.out | 21 ++++++
2 files changed, 164 insertions(+)
create mode 100755 tests/generic/2302
create mode 100644 tests/generic/2302.out
diff --git a/tests/generic/2302 b/tests/generic/2302
new file mode 100755
index 000000000000..5fff1f5e5015
--- /dev/null
+++ b/tests/generic/2302
@@ -0,0 +1,143 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Christoph Hellwig
+#
+# FS QA Test No. 2302
+#
+# Test that T10 DIF detects bitflips and misplaced writes.
+#
+. ./common/preamble
+_begin_fstest auto rw
+
+_cleanup()
+{
+ cd /
+ rm -r -f $tmp.*
+ [ -d "$SCSI_DEBUG_MNT" ] && _unmount $SCSI_DEBUG_MNT 2>/dev/null
+ _put_scsi_debug_dev
+}
+
+. ./common/scsi_debug
+. ./common/filter
+
+_require_scsi_debug
+# If TEST_DEV is block device, make sure current fs is a localfs which can be
+# written on scsi_debug device
+_require_test
+_require_block_device $TEST_DEV
+
+# FIEMAP on Btrfs returns logical addresses within the filesystem's address
+# space, not physical device offsets. Writing to these offsets on $SCRATCH_DEV
+# would corrupt the filesystem in multi-device setups.
+_exclude_fs btrfs
+
+size=$(_small_fs_size_mb 256)
+
+# Get the physical block offset (in bytes) of the file's first block on device
+get_phys_blk()
+{
+ local file="$1"
+ local fiemap_output
+ local phys_blk
+
+ fiemap_output=$($XFS_IO_PROG -r -c "fiemap -v" "$file" 2>/dev/null)
+ phys_blk=$(echo "$fiemap_output" | _filter_xfs_io_fiemap | head -1 | awk '{print $3}')
+ if [ -z "$phys_blk" ]; then
+ echo ""
+ return
+ fi
+ echo $phys_blk
+}
+
+test_dif()
+{
+ local pi_type=$1
+ local last=$2
+ local bit_errors=$3
+ local reftag_adjust=$4
+
+ echo -n "Testing DIF type $pi_type "
+ if [ "$bit_errors" -gt "0" ]; then
+ echo -n "bit errors ($bit_errors) in "
+ fi
+ if [ "$reftag_adjust" -ne "0" ]; then
+ echo -n "reftag adjustment by $reftag_adjust in "
+ fi
+ if [ "$last" -eq 1 ]; then
+ echo "last sector"
+ else
+ echo "first sector"
+ fi
+
+ scsi_debug_pi_opts="write_same_length=0 dif=${pi_type} dix=1"
+ SCSI_DEBUG_DEV=`_get_scsi_debug_dev 512 512 0 $size $scsi_debug_pi_opts`
+
+ SCSI_DEBUG_MNT="$TEST_DIR/scsi_debug_$seq"
+ rm -rf $SCSI_DEBUG_MNT
+ mkdir $SCSI_DEBUG_MNT
+
+ _mkfs_dev $SCSI_DEBUG_DEV || \
+ _fail "Can't make $FSTYP on DIF-enabled scsi_debug device"
+ run_check _mount $SCSI_DEBUG_DEV $SCSI_DEBUG_MNT
+
+ local blksz=$(_get_block_size $SCSI_DEBUG_MNT)
+ local testfile="$SCSI_DEBUG_MNT/test"
+
+ $XFS_IO_PROG -d -f \
+ -c "pwrite -S 0x66 0 $((128 * blksz))" \
+ -c fsync \
+ $testfile >> $seqres.full 2>&1
+
+ local phys_blk=$(get_phys_blk $testfile)
+ if [ -z "$phys_blk" ]; then
+ _fail "$test_name: failed to get physical block offset via fiemap"
+ fi
+
+ local dev=$(_short_dev $SCSI_DEBUG_DEV)
+ local debugfs_dir=$(ls /sys/block/$dev/device/scsi_device/)
+ local debugfs_file="/sys/kernel/debug/scsi_debug/$debugfs_dir/corrupt"
+
+ if [ ! -f "$debugfs_file" ]; then
+ _notrun "scsi_debug corruption injection not supported"
+ fi
+
+ if [ "$last" -eq 1 ]; then
+ echo "adding to $phys_blk" >> $seqres.full
+ phys_blk=$((phys_blk + 127))
+ fi
+
+ echo "lba=$phys_blk,num=1,bit_errors=$bit_errors,reftag_adjust=$reftag_adjust" \
+ > $debugfs_file
+
+ $XFS_IO_PROG -d -f \
+ -c "pread 0 $((128 * blksz))" \
+ $testfile
+
+ [ -d "$SCSI_DEBUG_MNT" ] && _unmount $SCSI_DEBUG_MNT 2>/dev/null
+ _put_scsi_debug_dev
+}
+
+# test data corruption in first block
+test_dif 1 0 2 0
+test_dif 2 0 2 0
+test_dif 3 0 2 0
+
+# test data corruption in last block
+test_dif 1 1 2 0
+test_dif 2 1 2 0
+test_dif 3 1 2 0
+
+
+# Note: Type 3 doesn't have a refrag, so don't test it
+
+# reftag mismatch in first block
+test_dif 1 0 0 8
+test_dif 2 0 0 8
+
+# reftag mismatch in last block
+test_dif 1 1 0 8
+test_dif 2 1 0 8
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/2302.out b/tests/generic/2302.out
new file mode 100644
index 000000000000..03b68d904943
--- /dev/null
+++ b/tests/generic/2302.out
@@ -0,0 +1,21 @@
+QA output created by 2302
+Testing DIF type 1 bit errors (2) in first sector
+pread: Invalid or incomplete multibyte or wide character
+Testing DIF type 2 bit errors (2) in first sector
+pread: Invalid or incomplete multibyte or wide character
+Testing DIF type 3 bit errors (2) in first sector
+pread: Invalid or incomplete multibyte or wide character
+Testing DIF type 1 bit errors (2) in last sector
+pread: Invalid or incomplete multibyte or wide character
+Testing DIF type 2 bit errors (2) in last sector
+pread: Invalid or incomplete multibyte or wide character
+Testing DIF type 3 bit errors (2) in last sector
+pread: Invalid or incomplete multibyte or wide character
+Testing DIF type 1 reftag adjustment by 8 in first sector
+pread: Invalid or incomplete multibyte or wide character
+Testing DIF type 2 reftag adjustment by 8 in first sector
+pread: Invalid or incomplete multibyte or wide character
+Testing DIF type 1 reftag adjustment by 8 in last sector
+pread: Invalid or incomplete multibyte or wide character
+Testing DIF type 2 reftag adjustment by 8 in last sector
+pread: Invalid or incomplete multibyte or wide character
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH 4/4] generic: test corruption detection using T10 protection information
2026-07-23 14:28 ` [PATCH 4/4] generic: test corruption detection using " Christoph Hellwig
@ 2026-08-02 11:57 ` Zorro Lang
0 siblings, 0 replies; 7+ messages in thread
From: Zorro Lang @ 2026-08-02 11:57 UTC (permalink / raw)
To: Christoph Hellwig
Cc: fstests, Martin K. Petersen, Kanchan Joshi, Anuj Gupta,
linux-scsi
On Thu, Jul 23, 2026 at 04:28:47PM +0200, Christoph Hellwig wrote:
> Add a test that simulates bit flips in data and misdirected writes and
> checks that file systems detect it when run on devices using protection
> information.
>
> This requires the new scsi_debug corruption injection.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> tests/generic/2302 | 143 +++++++++++++++++++++++++++++++++++++++++
> tests/generic/2302.out | 21 ++++++
> 2 files changed, 164 insertions(+)
> create mode 100755 tests/generic/2302
> create mode 100644 tests/generic/2302.out
>
> diff --git a/tests/generic/2302 b/tests/generic/2302
> new file mode 100755
> index 000000000000..5fff1f5e5015
> --- /dev/null
> +++ b/tests/generic/2302
> @@ -0,0 +1,143 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2026 Christoph Hellwig
> +#
> +# FS QA Test No. 2302
> +#
> +# Test that T10 DIF detects bitflips and misplaced writes.
> +#
> +. ./common/preamble
> +_begin_fstest auto rw
> +
> +_cleanup()
> +{
> + cd /
> + rm -r -f $tmp.*
> + [ -d "$SCSI_DEBUG_MNT" ] && _unmount $SCSI_DEBUG_MNT 2>/dev/null
> + _put_scsi_debug_dev
> +}
> +
> +. ./common/scsi_debug
> +. ./common/filter
> +
> +_require_scsi_debug
> +# If TEST_DEV is block device, make sure current fs is a localfs which can be
> +# written on scsi_debug device
> +_require_test
> +_require_block_device $TEST_DEV
> +
> +# FIEMAP on Btrfs returns logical addresses within the filesystem's address
> +# space, not physical device offsets. Writing to these offsets on $SCRATCH_DEV
> +# would corrupt the filesystem in multi-device setups.
> +_exclude_fs btrfs
> +
> +size=$(_small_fs_size_mb 256)
> +
> +# Get the physical block offset (in bytes) of the file's first block on device
> +get_phys_blk()
> +{
> + local file="$1"
> + local fiemap_output
> + local phys_blk
> +
> + fiemap_output=$($XFS_IO_PROG -r -c "fiemap -v" "$file" 2>/dev/null)
_require_xfs_io_command fiemap
> + phys_blk=$(echo "$fiemap_output" | _filter_xfs_io_fiemap | head -1 | awk '{print $3}')
This logic looks like common/rc:_get_file_extent_sector(), can this
function help?
> + if [ -z "$phys_blk" ]; then
> + echo ""
> + return
> + fi
> + echo $phys_blk
> +}
> +
> +test_dif()
> +{
> + local pi_type=$1
> + local last=$2
> + local bit_errors=$3
> + local reftag_adjust=$4
> +
> + echo -n "Testing DIF type $pi_type "
> + if [ "$bit_errors" -gt "0" ]; then
> + echo -n "bit errors ($bit_errors) in "
> + fi
> + if [ "$reftag_adjust" -ne "0" ]; then
> + echo -n "reftag adjustment by $reftag_adjust in "
> + fi
> + if [ "$last" -eq 1 ]; then
> + echo "last sector"
> + else
> + echo "first sector"
> + fi
> +
> + scsi_debug_pi_opts="write_same_length=0 dif=${pi_type} dix=1"
> + SCSI_DEBUG_DEV=`_get_scsi_debug_dev 512 512 0 $size $scsi_debug_pi_opts`
> +
> + SCSI_DEBUG_MNT="$TEST_DIR/scsi_debug_$seq"
> + rm -rf $SCSI_DEBUG_MNT
> + mkdir $SCSI_DEBUG_MNT
> +
> + _mkfs_dev $SCSI_DEBUG_DEV || \
> + _fail "Can't make $FSTYP on DIF-enabled scsi_debug device"
> + run_check _mount $SCSI_DEBUG_DEV $SCSI_DEBUG_MNT
> +
> + local blksz=$(_get_block_size $SCSI_DEBUG_MNT)
> + local testfile="$SCSI_DEBUG_MNT/test"
> +
> + $XFS_IO_PROG -d -f \
_require_odirect ?
> + -c "pwrite -S 0x66 0 $((128 * blksz))" \
> + -c fsync \
> + $testfile >> $seqres.full 2>&1
> +
> + local phys_blk=$(get_phys_blk $testfile)
> + if [ -z "$phys_blk" ]; then
> + _fail "$test_name: failed to get physical block offset via fiemap"
> + fi
> +
> + local dev=$(_short_dev $SCSI_DEBUG_DEV)
> + local debugfs_dir=$(ls /sys/block/$dev/device/scsi_device/)
> + local debugfs_file="/sys/kernel/debug/scsi_debug/$debugfs_dir/corrupt"
_require_debugfs
> +
> + if [ ! -f "$debugfs_file" ]; then
> + _notrun "scsi_debug corruption injection not supported"
> + fi
> +
> + if [ "$last" -eq 1 ]; then
> + echo "adding to $phys_blk" >> $seqres.full
> + phys_blk=$((phys_blk + 127))
> + fi
> +
> + echo "lba=$phys_blk,num=1,bit_errors=$bit_errors,reftag_adjust=$reftag_adjust" \
> + > $debugfs_file
> +
> + $XFS_IO_PROG -d -f \
> + -c "pread 0 $((128 * blksz))" \
> + $testfile
> +
> + [ -d "$SCSI_DEBUG_MNT" ] && _unmount $SCSI_DEBUG_MNT 2>/dev/null
> + _put_scsi_debug_dev
> +}
> +
> +# test data corruption in first block
> +test_dif 1 0 2 0
> +test_dif 2 0 2 0
> +test_dif 3 0 2 0
> +
> +# test data corruption in last block
> +test_dif 1 1 2 0
> +test_dif 2 1 2 0
> +test_dif 3 1 2 0
> +
> +
> +# Note: Type 3 doesn't have a refrag, so don't test it
> +
> +# reftag mismatch in first block
> +test_dif 1 0 0 8
> +test_dif 2 0 0 8
> +
> +# reftag mismatch in last block
> +test_dif 1 1 0 8
> +test_dif 2 1 0 8
> +
> +# success, all done
> +status=0
> +exit
_exit 0
> diff --git a/tests/generic/2302.out b/tests/generic/2302.out
> new file mode 100644
> index 000000000000..03b68d904943
> --- /dev/null
> +++ b/tests/generic/2302.out
> @@ -0,0 +1,21 @@
> +QA output created by 2302
> +Testing DIF type 1 bit errors (2) in first sector
> +pread: Invalid or incomplete multibyte or wide character
> +Testing DIF type 2 bit errors (2) in first sector
> +pread: Invalid or incomplete multibyte or wide character
> +Testing DIF type 3 bit errors (2) in first sector
> +pread: Invalid or incomplete multibyte or wide character
> +Testing DIF type 1 bit errors (2) in last sector
> +pread: Invalid or incomplete multibyte or wide character
> +Testing DIF type 2 bit errors (2) in last sector
> +pread: Invalid or incomplete multibyte or wide character
> +Testing DIF type 3 bit errors (2) in last sector
> +pread: Invalid or incomplete multibyte or wide character
> +Testing DIF type 1 reftag adjustment by 8 in first sector
> +pread: Invalid or incomplete multibyte or wide character
> +Testing DIF type 2 reftag adjustment by 8 in first sector
> +pread: Invalid or incomplete multibyte or wide character
> +Testing DIF type 1 reftag adjustment by 8 in last sector
> +pread: Invalid or incomplete multibyte or wide character
> +Testing DIF type 2 reftag adjustment by 8 in last sector
> +pread: Invalid or incomplete multibyte or wide character
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 7+ messages in thread