[PATCH v4 3/3] md/raid5: warn when a read fails due in some part to bad-block metadata
DORMANTno replies
From: Doug V Johnson <hidden>
Date: 2026-10-16 04:25:49
Also in:
lkml
Subsystem:
software raid (multiple disks) support, the rest · Maintainers:
Song Liu, Yu Kuai, Linus Torvalds
Report that bad block metadata contributed to a read failure on the array so that it's clear that the failure may not be directly due to an immediate underlying device read failure. There has been a documented case of bad block metadata being erroneously copied around contributing to mystery read failures with no underlying device failure. This warning will help users understand why the failure exists and may lead to the discovery of this condition sooner. Link: https://lore.kernel.org/r/20250224090209.2077-2-dougvj@dougvj.net (local) Link: https://lkml.iu.edu/2501.3/01088.html Assisted-by: LLM Signed-off-by: Doug V Johnson <redacted> --- drivers/md/raid5.c | 16 ++++++++++++++++ drivers/md/raid5.h | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 23ff549fa363..f721eb97f655 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c@@ -3672,6 +3672,16 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh, wake_up_bit(&sh->dev[i].flags, R5_Overlap); if (bi) s->to_read--; + /* + * If we recorded bad blocks from the metadata + * on any of the devices then report this to + * userspace in case anyone might suspect + * something more fundamental instead + */ + if (bi && s->bad_blocks) + pr_warn_ratelimited("%s: read encountered block in device bad block list at %llu\n", + mdname(conf->mddev), + (unsigned long long)sh->sector); while (bi && bi->bi_iter.bi_sector < sh->dev[i].sector + RAID5_STRIPE_SECTORS(conf)) { struct bio *nextbi =
@@ -4764,6 +4774,12 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) if (rdev) { is_bad = rdev_has_badblock(rdev, sh->sector, RAID5_STRIPE_SECTORS(conf)); + if (is_bad) { + s->bad_blocks++; + pr_debug("bad blocks encountered dev %i sector %llu %lu\n", + i, (unsigned long long)sh->sector, + (unsigned long)RAID5_STRIPE_SECTORS(conf)); + } if (s->blocked_rdev == NULL) { if (is_bad < 0) set_bit(BlockedBadBlocks, &rdev->flags);
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index cb5feae04db2..6b90c9565ec0 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h@@ -282,7 +282,7 @@ struct stripe_head_state { * read all devices, just the replacement targets. */ int syncing, expanding, expanded, replacing; - int locked, uptodate, to_read, to_write, failed, written; + int locked, uptodate, to_read, to_write, failed, written, bad_blocks; int to_fill, compute, req_compute, non_overwrite; int injournal, just_cached; int failed_num[2];
--
2.54.0