md: mark rdev Faulty when badblocks setting fails

Currently when sync read fails and badblocks set fails (exceeding
512 limit), rdev isn't immediately marked Faulty. Instead
'recovery_disabled' is set and non-In_sync rdevs are removed later.
This preserves array availability if bad regions aren't read, but bad
sectors might be read by users before rdev removal. This occurs due
to incorrect resync/recovery_offset updates that include these bad
sectors.

When badblocks exceed 512, keeping the disk provides little benefit
while adding complexity. Prompt disk replacement is more important.
Therefore when badblocks set fails, directly call md_error to mark rdev
Faulty immediately, preventing potential data access issues.

After this change, cleanup of offset update logic and 'recovery_disabled'
handling will follow.

Link: https://lore.kernel.org/linux-raid/20260105110300.1442509-6-linan666@huaweicloud.com
Fixes: 5e5702898e ("md/raid10: Handle read errors during recovery better.")
Fixes: 3a9f28a511 ("md/raid1: improve handling of read failure during recovery.")
Signed-off-by: Li Nan <linan122@huawei.com>
Signed-off-by: Yu Kuai <yukuai@fnnas.com>
This commit is contained in:
Li Nan
2026-01-05 19:02:53 +08:00
committed by Yu Kuai
parent aa9d12cfa1
commit fd4d44c14f
4 changed files with 32 additions and 45 deletions

View File

@@ -10422,8 +10422,14 @@ bool rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors,
else
s += rdev->data_offset;
if (!badblocks_set(&rdev->badblocks, s, sectors, 0))
if (!badblocks_set(&rdev->badblocks, s, sectors, 0)) {
/*
* Mark the disk as Faulty when setting badblocks fails,
* otherwise, bad sectors may be read.
*/
md_error(mddev, rdev);
return false;
}
/* Make sure they get written out promptly */
if (test_bit(ExternalBbl, &rdev->flags))