From: FengWei Shih Date: Thu, 19 Mar 2026 05:33:51 +0000 (+0800) Subject: md/raid5: skip 2-failure compute when other disk is R5_LOCKED X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=52e4324935be917f8f3267354b3cc06bb8ffcec1;p=thirdparty%2Fkernel%2Flinux.git md/raid5: skip 2-failure compute when other disk is R5_LOCKED When skip_copy is enabled on a doubly-degraded RAID6, a device that is being written to will be in R5_LOCKED state with R5_UPTODATE cleared. If a new read triggers fetch_block() while the write is still in flight, the 2-failure compute path may select this locked device as a compute target because it is not R5_UPTODATE. Because skip_copy makes the device page point directly to the bio page, reconstructing data into it might be risky. Also, since the compute marks the device R5_UPTODATE, it triggers WARN_ON in ops_run_io() which checks that R5_SkipCopy and R5_UPTODATE are not both set. This can be reproduced by running small-range concurrent read/write on a doubly-degraded RAID6 with skip_copy enabled, for example: mdadm -C /dev/md0 -l6 -n6 -R -f /dev/loop[0-3] missing missing echo 1 > /sys/block/md0/md/skip_copy fio --filename=/dev/md0 --rw=randrw --bs=4k --numjobs=8 \ --iodepth=32 --size=4M --runtime=30 --time_based --direct=1 Fix by checking R5_LOCKED before proceeding with the compute. The compute will be retried once the lock is cleared on IO completion. Signed-off-by: FengWei Shih Reviewed-by: Yu Kuai Link: https://lore.kernel.org/linux-raid/20260319053351.3676794-1-dannyshih@synology.com/ Signed-off-by: Yu Kuai --- diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 2ec6dd6ddd93f..ddac1be2648f0 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3916,6 +3916,8 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s, break; } BUG_ON(other < 0); + if (test_bit(R5_LOCKED, &sh->dev[other].flags)) + return 0; pr_debug("Computing stripe %llu blocks %d,%d\n", (unsigned long long)sh->sector, disk_idx, other);