git: e5283a9da86a - main - graid3: Add rotation rate support

From: Alexander Motin <mav_at_FreeBSD.org>
Date: Sat, 29 Aug 2026 18:00:15 UTC
The branch main has been updated by mav:

URL: https://cgit.FreeBSD.org/src/commit/?id=e5283a9da86a0080ab0267bcbff4febb049d323d

commit e5283a9da86a0080ab0267bcbff4febb049d323d
Author:     Alexander Motin <mav@FreeBSD.org>
AuthorDate: 2026-08-29 17:59:05 +0000
Commit:     Alexander Motin <mav@FreeBSD.org>
CommitDate: 2026-08-29 18:00:02 +0000

    graid3: Add rotation rate support
    
    If all member devices report the same rotation rate, pass it up.
---
 sys/geom/raid3/g_raid3.c | 33 +++++++++++++++++++++++++++++++++
 sys/geom/raid3/g_raid3.h |  1 +
 2 files changed, 34 insertions(+)

diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c
index 64951bd01deb..0436d9286532 100644
--- a/sys/geom/raid3/g_raid3.c
+++ b/sys/geom/raid3/g_raid3.c
@@ -47,6 +47,7 @@
 
 #include <geom/geom.h>
 #include <geom/geom_dbg.h>
+#include <geom/geom_disk.h>
 #include <geom/raid3/g_raid3.h>
 
 FEATURE(geom_raid3, "GEOM RAID-3 functionality");
@@ -564,6 +565,10 @@ g_raid3_init_disk(struct g_raid3_softc *sc, struct g_provider *pp,
 	}
 	disk->d_state = G_RAID3_DISK_STATE_NONE;
 	disk->d_flags = md->md_dflags;
+	error = g_getattr("GEOM::rotation_rate", disk->d_consumer,
+	    &disk->d_rotation_rate);
+	if (error != 0)
+		disk->d_rotation_rate = DISK_RR_UNKNOWN;
 	if (md->md_provider[0] != '\0')
 		disk->d_flags |= G_RAID3_DISK_FLAG_HARDCODED;
 	disk->d_sync.ds_consumer = NULL;
@@ -1451,6 +1456,29 @@ g_raid3_flush(struct g_raid3_softc *sc, struct bio *bp)
 	}
 }
 
+static void
+g_raid3_rotation_rate(struct g_raid3_softc *sc, struct bio *bp)
+{
+	struct g_raid3_disk *disk;
+	bool first = true;
+	uint16_t rr = DISK_RR_UNKNOWN;
+	u_int n;
+
+	for (n = 0; n < sc->sc_ndisks; n++) {
+		disk = &sc->sc_disks[n];
+		if (disk->d_state == G_RAID3_DISK_STATE_NODISK)
+			continue;
+		if (first)
+			rr = disk->d_rotation_rate;
+		else if (rr != disk->d_rotation_rate) {
+			rr = DISK_RR_UNKNOWN;
+			break;
+		}
+		first = false;
+	}
+	g_handleattr(bp, "GEOM::rotation_rate", &rr, sizeof(rr));
+}
+
 static void
 g_raid3_start(struct bio *bp)
 {
@@ -1477,6 +1505,11 @@ g_raid3_start(struct bio *bp)
 		g_raid3_flush(sc, bp);
 		return;
 	case BIO_GETATTR:
+		if (!strcmp(bp->bio_attribute, "GEOM::rotation_rate")) {
+			g_raid3_rotation_rate(sc, bp);
+			return;
+		}
+		/* FALLTHROUGH */
 	default:
 		g_io_deliver(bp, EOPNOTSUPP);
 		return;
diff --git a/sys/geom/raid3/g_raid3.h b/sys/geom/raid3/g_raid3.h
index 3eecc02798a9..8650de2527b1 100644
--- a/sys/geom/raid3/g_raid3.h
+++ b/sys/geom/raid3/g_raid3.h
@@ -124,6 +124,7 @@ struct g_raid3_disk {
 	struct g_consumer *d_consumer;	/* Consumer. */
 	struct g_raid3_softc *d_softc;	/* Back-pointer to softc. */
 	int		 d_state;	/* Disk state. */
+	uint16_t	 d_rotation_rate;/* Disk's rotation rate. */
 	uint64_t	 d_flags;	/* Additional flags. */
 	u_int		 d_genid;	/* Disk's generation ID. */
 	struct g_raid3_disk_sync d_sync; /* Sync information. */