Thread (1 message) 1 message, 1 author, 1d ago

[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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help