[PATCH] xfs: test case for handling io errors when reading extended attributes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We've seen reports from the field panicing in xfs_trans_brelse after
an io error for an attribute block.

sd 0:0:23:0: [sdx] tag#271 CDB: Read(16) 88 00 00 00 00 00 9b df 5e 78 00 00 00 08 00 00
critical medium error, dev sdx, sector 2615107192 op 0x0:(READ) flags 0x1000 phys_seg 1 prio class 2
XFS (sdx1): metadata I/O error in "xfs_da_read_buf+0xe1/0x140 [xfs]" at daddr 0x9bdf5678 len 8 error 61
BUG: kernel NULL pointer dereference, address: 00000000000000e0
...
RIP: 0010:xfs_trans_brelse+0xb/0xe0 [xfs]
...
Call Trace:
 <TASK>
...
 ? xfs_trans_brelse+0xb/0xe0 [xfs]
 xfs_attr_leaf_get+0xb6/0xc0 [xfs]
 xfs_attr_get+0xa0/0xd0 [xfs]
 xfs_xattr_get+0x75/0xb0 [xfs]
 __vfs_getxattr+0x53/0x70
 inode_doinit_use_xattr+0x63/0x180
 inode_doinit_with_dentry+0x196/0x510
 security_d_instantiate+0x2f/0x50
 d_splice_alias+0x46/0x2b0
 xfs_vn_lookup+0x8b/0xb0 [xfs]
 __lookup_slow+0x84/0x130
 walk_component+0x158/0x1d0
 path_lookupat+0x6e/0x1c0
 filename_lookup+0xcf/0x1d0
 vfs_statx+0x8d/0x170
 vfs_fstatat+0x54/0x70
 __do_sys_newfstatat+0x26/0x60

This was an unsuccessful attempt to reproduce this using dmerror.

It should provoke the problem if a system tap or custom kernel is used
to return ENODATA as seen above, and not EIO as returned by dmerror.

Signed-off-by: Donald Douwsma <ddouwsma@xxxxxxxxxx>
---
 tests/xfs/999     | 107 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/999.out |   2 +
 2 files changed, 109 insertions(+)
 create mode 100755 tests/xfs/999
 create mode 100644 tests/xfs/999.out

diff --git a/tests/xfs/999 b/tests/xfs/999
new file mode 100755
index 00000000..627ca14e
--- /dev/null
+++ b/tests/xfs/999
@@ -0,0 +1,107 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 YOUR NAME HERE.  All Rights Reserved.
+#
+# FS QA Test 601
+#
+# what am I here for?
+# Test for panic during ioerror reading xattr blocks
+#
+. ./common/preamble
+_begin_fstest auto
+
+# Override the default cleanup function.
+_cleanup()
+{
+	cd /
+	rm -f $tmp.*
+	_dmerror_cleanup
+}
+
+# Import common functions.
+# . ./common/filter
+. ./common/dmerror
+
+# real QA test starts here
+
+# Modify as appropriate.
+_require_scratch
+_require_dm_target error
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+
+# TODO: Avoid assumptions about inode size using _xfs_get_inode_size and
+#       _xfs_get_inode_core_bytes, currently assuming 512 byte inodes.
+
+# Shortform
+# Include shortform for completeness, we can only inject errors for attributes
+# stored outside of the inode.
+testfile="$SCRATCH_MNT/attr_shortform"
+touch $testfile
+ls -i $testfile >> $seqres.full
+setfattr -n user.test_shortform -v $(printf "%0.12d" 12) $testfile
+
+# leaf with single block extent
+testfile="$SCRATCH_MNT/attr_leaf_oneblock"
+touch $testfile
+ls -i $testfile >> $seqres.full
+setfattr -n user.test_leaf -v $(printf "%0.512d" 512) $testfile
+
+# leaf with single multiple block extent
+testfile="$SCRATCH_MNT/attr_leaf_twoblocks"
+touch $testfile
+ls -i $testfile >> $seqres.full
+inode=$(ls -i $testfile|awk '{print $1}')
+setfattr -n user.test_leaf -v $(printf "%0.5000d" 5000) $testfile
+
+# Generalise to for multiple attributes accross many blocks
+# size_name=
+# size_val=256 # how dows value>block-size work out?
+# num_attrs=2022
+# testfile="$SCRATCH_MNT/attr_leaf_manyblocks"
+# touch $testfile
+# ls -li $testfile
+# inode=$(ls -i $testfile|awk '{print $1}')
+#
+# for n_attr in $(seq 0 $num_attrs); do
+#	echo $n_attr;
+#	setfattr -n $(printf "user.test_leaf_%04d" $n_attr) \
+#		 -v $(printf "%0.${size_val}d" $size_val) \
+#		 $testfile
+# done
+
+$XFS_IO_PROG -c "bmap -al" $testfile >> $seqres.full
+attrblocks=($($XFS_IO_PROG -c "bmap -al" $testfile | awk 'match($3, /[0-9]+/, a) {print a[0]}'))
+echo Attribute fork at blocks ${attrblocks[*]} >> $seqres.full
+
+_scratch_unmount
+
+echo "Dump inode $inode details with xfs_db" >> $seqres.full
+# _scratch_xfs_db -c "inode $inode" -c "print core.aformat core.naextents a" >> $seqres.full
+_scratch_xfs_db -c "inode $inode" -c print >> $seqres.full
+
+_dmerror_init >> $seqres.full 2>&1
+_dmerror_reset_table >> $seqres.full 2>&1
+_dmerror_mount >> $seqres.full 2>&1
+
+echo "Setup dm-error when reading the second attribute block ${attrblocks[1]}" >> $seqres.full
+_dmerror_mark_range_bad ${attrblocks[1]} 1 $SCRATCH_DEV
+
+# Debug from tests/xfs/556
+cat >> $seqres.full << ENDL
+dmerror after marking bad:
+$DMERROR_TABLE
+$DMERROR_RTTABLE
+<end table>
+ENDL
+
+_dmerror_load_error_table
+
+# Panic here if failure
+echo "Re-read the extended attribute, panics on unandled ioerrors" >> $seqres.full
+getfattr -d -m - $testfile >> $seqres.full
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/999.out b/tests/xfs/999.out
new file mode 100644
index 00000000..e7f4becf
--- /dev/null
+++ b/tests/xfs/999.out
@@ -0,0 +1,2 @@
+QA output created by 999 
+Silence is golden
-- 
2.47.3





[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux