From: Donald Douwsma <ddouwsma@redhat.com>
To: Zorro Lang <zlang@redhat.com>
Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org,
Zorro Lang <zlang@kernel.org>
Subject: Re: [PATCH v3] xfs: test case for handling io errors when reading extended attributes
Date: Thu, 20 Nov 2025 12:15:06 +1100 [thread overview]
Message-ID: <193ae927-9a53-4fa0-9cbe-4e677af2525c@redhat.com> (raw)
In-Reply-To: <20251119100709.zbkenjwztblkjobd@dell-per750-06-vm-08.rhts.eng.pek2.redhat.com>
On 19/11/25 21:07, Zorro Lang wrote:
> On Wed, Nov 19, 2025 at 03:12:10PM +1100, Donald Douwsma wrote:
>> We've seen reports from the field panicking in xfs_trans_brelse after an
>> IO error when reading 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]
>>
>> Signed-off-by: Donald Douwsma <ddouwsma@redhat.com>
>>
>> ---
>> V3
>> - Zorro's suggestions (_require_scsi_debug, _require_scratch, ..., use _get_file_block_size
>> drop dry_run, fix local variables and parameters, common/attr, ...)
>> - Override SELINUX_MOUNT_OPTIONS to avoid _scratch_mount breaking the test
>> - Add test to quick attr
>> - Change test_attr() to work with blocks instead of bytes
>> - Name the scsi_debug options to make it clearer where the error is active
>> - Determine size of the attr value required based on filesystem block size
>> V2
>> - As this is specific to ENODATA test using scsi_debug instead of dmerror
>> which returns EIO.
>> ---
>> common/scsi_debug | 8 ++-
>> tests/xfs/999 | 139 ++++++++++++++++++++++++++++++++++++++++++++++
>> tests/xfs/999.out | 2 +
>> 3 files changed, 148 insertions(+), 1 deletion(-)
>> create mode 100755 tests/xfs/999
>> create mode 100644 tests/xfs/999.out
>>
>> diff --git a/common/scsi_debug b/common/scsi_debug
>> index 1e0ca255..c3fe7be6 100644
>> --- a/common/scsi_debug
>> +++ b/common/scsi_debug
>> @@ -6,6 +6,7 @@
>>
>> . common/module
>>
>> +# _require_scsi_debug [mod_param]
>> _require_scsi_debug()
>> {
>> local mod_present=0
>> @@ -30,9 +31,14 @@ _require_scsi_debug()
>> _patient_rmmod scsi_debug || _notrun "scsi_debug module in use"
>> fi
>> fi
>> +
>> # make sure it has the features we need
>> # logical/physical sectors plus unmap support all went in together
>> - modinfo scsi_debug | grep -wq sector_size || _notrun "scsi_debug too old"
>> + grep -wq sector_size <(modinfo scsi_debug) || _notrun "scsi_debug too old"
>> + # make sure it supports this module parameter
>> + if [ -n "$1" ];then
>> + grep -Ewq "$1" <(modinfo scsi_debug) || _notrun "scsi_debug not support $1"
>> + fi
>> }
>>
>> # Args: [physical sector size, [logical sector size, [unaligned(0|1), [size in megs]]]]
>> diff --git a/tests/xfs/999 b/tests/xfs/999
>> new file mode 100755
>> index 00000000..2a571195
>> --- /dev/null
>> +++ b/tests/xfs/999
>> @@ -0,0 +1,139 @@
>> +#!/bin/bash
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (c) 2025 Red Hat Inc. All Rights Reserved.
>> +#
>> +# FS QA Test 999
>> +#
>> +# Regression test for panic following IO error when reading extended attribute blocks
>> +#
>> +# XFS (sda): metadata I/O error in "xfs_da_read_buf+0xe1/0x140 [xfs]" at daddr 0x78 len 8 error 61
>> +# BUG: kernel NULL pointer dereference, address: 00000000000000e0
>> +# ...
>> +# RIP: 0010:xfs_trans_brelse+0xb/0xe0 [xfs]
>> +#
>> +# For SELinux enabled filesystems the attribute security.selinux will be
>> +# created before any additional attributes are added. In this case the
>> +# regression will trigger via security_d_instantiate() during a stat(2),
>> +# without SELinux this should trigger from fgetxattr(2).
>> +#
>> +# Kernels prior to v4.16 don't have medium_error_start, and only return errors
>> +# for a specific location, making scsi_debug unsuitable for checking old
>> +# kernels. See d9da891a892a scsi: scsi_debug: Add two new parameters to
>> +# scsi_debug driver
>> +#
>> +
>> +. ./common/preamble
>> +_begin_fstest auto quick attr
>> +
>> +_fixed_by_kernel_commit ae668cd567a6 \
>> + "xfs: do not propagate ENODATA disk errors into xattr code"
>> +
>> +# Override the default cleanup function.
>> +_cleanup()
>> +{
>> + _unmount $SCRATCH_MNT 2>/dev/null
>> + _put_scsi_debug_dev
>> + cd /
>> + rm -f $tmp.*
>> +}
>> +
>> +# Import common functions.
>> +. ./common/attr
>> +. ./common/scsi_debug
>> +
>> +_require_scratch_nocheck
>> +_require_scsi_debug "medium_error_start"
>> +_require_attrs user
>> +
>> +# If SELinux is enabled common/config sets a default context, which which breaks this test.
> ^^^^^
>
>> +export SELINUX_MOUNT_OPTIONS=""
>> +
>> +scsi_debug_dev=$(_get_scsi_debug_dev)
>> +scsi_debug_opt_noerror=0
>> +scsi_debug_opt_error=${scsi_debug_opt_error:=2}
>> +test -b $scsi_debug_dev || _notrun "Failed to initialize scsi debug device"
>> +echo "SCSI debug device $scsi_debug_dev" >>$seqres.full
>> +
>> +SCRATCH_DEV=$scsi_debug_dev
>> +_scratch_mkfs >> $seqres.full
>> +_scratch_mount
>> +
>> +block_size=$(_get_file_block_size $SCRATCH_MNT)
>> +inode_size=$(_xfs_get_inode_size $SCRATCH_MNT)
>> +error_length=$((block_size/512)) # Error all sectors in the block
>> +
>> +echo Block size $block_size >> $seqres.full
>> +echo Inode size $inode_size >> $seqres.full
>> +
>> +test_attr()
>> +{
>> + local test=$1
>> + local testfile=$SCRATCH_MNT/$test
>> + local attr_blocks=$2
>> + local error_at_block=${3:-0}
>> +
>> + local attr_size_bytes=$((block_size/2*attr_blocks))
>> +
>> + # The maximum size for a single value is ATTR_MAX_VALUELEN (64*1024)
>> + # If we wanted to test a larger range of extent combinations the test
>> + # would need to use multiple values.
>> + [[ $attr_size_bytes -ge 65536 ]] && echo "Test would need to be modified to support > 64k values for $attr_blocks blocks".
>> +
>> + echo $scsi_debug_opt_noerror > /sys/module/scsi_debug/parameters/opts
>> +
>> + echo -e "\nTesting : $test" >> $seqres.full
>> + echo -e "attr size: $attr_blocks" >> $seqres.full
>> + echo -e "error at block: $error_at_block\n" >> $seqres.full
>> +
>> + touch $testfile
>> + local inode=$(stat -c '%i' $testfile)
>> + $SETFATTR_PROG -n user.test_attr -v $(printf "%0*d" $attr_size_bytes $attr_size_bytes) $testfile
>> +
>> + $XFS_IO_PROG -c "bmap -al" $testfile >> $seqres.full
>> + start_blocks=($($XFS_IO_PROG -c "bmap -al" $testfile | awk 'match($3, /[0-9]+/, a) {print a[0]}'))
> ^^^^^^^^^^^^
> local start_blocks
>
>
> OK, so you still don't want to use:
>
> local start_blocks=$(_scratch_xfs_get_metadata_field "a.bmx[0].startblock" "inode $inode")
I'm used to looking at extent information on mounted filesystems with xfs_bmap,
so it felt more natural.
I also wanted to make it easy to extend this to btree format attr if required.
It may be possible to do that with _scratch_xfs_get_metadata_field if it works
with btdump, but would add complexity.
> Anyway, both ways are good to get the start_blocks for this case. So ... (don't need to send v4)
>
> Reviewed-by: Zorro Lang <zlang@redhat.com>
>
Thanks for your help and feedback with this,
Don
>> + echo "Attribute fork extent(s) start at ${start_blocks[*]}" >> $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
>> +
>> + if [[ start_blocks[0] -ne 0 ]]; then
>> + # Choose the block to error, currently only works with a single extent.
>> + error_daddr=$((start_blocks[0] + error_at_block*block_size/512))
>> + else
>> + # Default to the inode daddr when no extents were found.
>> + # Errors when getfattr(1) stats the inode and doesnt get to getfattr(2)
>> + error_daddr=$(_scratch_xfs_db -c "inode $inode" -c "daddr" | awk '{print $4}')
>> + fi
>> +
>> + _scratch_mount
>> +
>> + echo "Setup scsi_debug to error when reading attributes from block" \
>> + "$error_at_block at daddr $error_daddr" >> $seqres.full
>> + echo $error_daddr > /sys/module/scsi_debug/parameters/medium_error_start
>> + echo $error_length > /sys/module/scsi_debug/parameters/medium_error_count
>> + echo $scsi_debug_opt_error > /sys/module/scsi_debug/parameters/opts
>> + grep ^ /sys/module/scsi_debug/parameters/{medium_error_start,medium_error_count,opts} >> $seqres.full
>> +
>> + echo "Read the extended attribute on $testfile" >> $seqres.full
>> + sync # the fstests logs to disk.
>> +
>> + _getfattr -d -m - $testfile >> $seqres.full 2>&1 # Panic here on failure
>> +}
>> +
>> +# aformat shortform
>> +test_attr "attr_local" 0 0
>> +
>> +# aformat extents
>> +# Single leaf block, known to panic
>> +test_attr "attr_extent_one_block" 1 0
>> +
>> +# Other tests to exercise multi block extents
>> +test_attr "attr_extent_two_blocks_1" 2 1
>> +test_attr "attr_extent_two_blocks_2" 2 2
>> +
>> +# success, all done
>> +echo Silence is golden
>> +status=0
>> +exit
>> diff --git a/tests/xfs/999.out b/tests/xfs/999.out
>> new file mode 100644
>> index 00000000..3b276ca8
>> --- /dev/null
>> +++ b/tests/xfs/999.out
>> @@ -0,0 +1,2 @@
>> +QA output created by 999
>> +Silence is golden
>> --
>> 2.47.3
>>
>>
>
prev parent reply other threads:[~2025-11-20 1:15 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-19 4:12 [PATCH v3] xfs: test case for handling io errors when reading extended attributes Donald Douwsma
2025-11-19 6:14 ` Christoph Hellwig
2025-11-19 10:07 ` Zorro Lang
2025-11-20 1:15 ` Donald Douwsma [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=193ae927-9a53-4fa0-9cbe-4e677af2525c@redhat.com \
--to=ddouwsma@redhat.com \
--cc=fstests@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
--cc=zlang@kernel.org \
--cc=zlang@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox