[PATCH 4/4] md: include events counters when kicking non-fresh device

Mykola Marzhan <[email protected]> Sun, 19 Jul 2026 14:44:09 +0000
Newsgroups org.kernel.vger.linux-raid,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
When analyze_sbs() kicks a member with a stale events counter, the
warning names the device but not the divergence that caused the
kick, so judging whether the kicked member is salvageable means
running mdadm --examine on every member.  Print the member's on-disk
events counter and the freshest events counter in the warning
itself.

rdev->sb_events cannot be used here: it is only assigned when a
superblock is written and still reads 0 during assemble.  Read the
counter from the superblock page instead -- md_event() for 0.90
metadata, the little-endian events field for 1.x.

The legacy substring "kicking non-fresh %pg from array!" is
unchanged, so existing log parsers continue to match.

Assisted-by: Claude-Code:claude-opus-4-8
Signed-off-by: Mykola Marzhan <[email protected]>
---
 drivers/md/md.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index d60ea7aaca3a..9ec87375a717 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3934,8 +3934,29 @@ static int analyze_sbs(struct mddev *mddev)
 		if (rdev != freshest) {
 			if (super_types[mddev->major_version].
 			    validate_super(mddev, freshest, rdev)) {
-				pr_warn("md: kicking non-fresh %pg from array!\n",
-					rdev->bdev);
+				u64 rdev_events = 0;
+
+				/*
+				 * rdev->sb_events is only assigned when
+				 * writing a superblock and reads 0 during
+				 * assemble; read events from the on-disk
+				 * superblock instead.
+				 */
+				if (rdev->sb_page) {
+					if (mddev->major_version == 1) {
+						struct mdp_superblock_1 *sb =
+							page_address(rdev->sb_page);
+						rdev_events = le64_to_cpu(sb->events);
+					} else if (mddev->major_version == 0) {
+						mdp_super_t *sb =
+							page_address(rdev->sb_page);
+						rdev_events = md_event(sb);
+					}
+				}
+				pr_warn("md: kicking non-fresh %pg from array! (events=%llu, freshest=%llu)\n",
+					rdev->bdev,
+					(unsigned long long)rdev_events,
+					(unsigned long long)mddev->events);
 				md_kick_rdev_from_array(rdev);
 				continue;
 			}
-- 
2.43.0