git: 2d9c41daac0b - main - graid: Add rotation rate support

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

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

commit 2d9c41daac0b1e7f35a88ee187ae98a233a30267
Author:     Alexander Motin <mav@FreeBSD.org>
AuthorDate: 2026-08-29 17:56:15 +0000
Commit:     Alexander Motin <mav@FreeBSD.org>
CommitDate: 2026-08-29 18:00:02 +0000

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

diff --git a/sys/geom/raid/g_raid.c b/sys/geom/raid/g_raid.c
index d35695482eea..e8bc61b5c657 100644
--- a/sys/geom/raid/g_raid.c
+++ b/sys/geom/raid/g_raid.c
@@ -47,6 +47,7 @@
 
 #include <geom/geom.h>
 #include <geom/geom_dbg.h>
+#include <geom/geom_disk.h>
 #include <geom/raid/g_raid.h>
 #include "g_raid_md_if.h"
 #include "g_raid_tr_if.h"
@@ -520,6 +521,11 @@ g_raid_get_disk_info(struct g_raid_disk *disk)
 		G_RAID_DEBUG1(2, disk->d_softc,
 		    "BIO_DELETE not supported by %s: %d.", 
 		    cp->provider->name, error);
+
+	/* Read rotation rate. */
+	error = g_getattr("GEOM::rotation_rate", cp, &disk->d_rotation_rate);
+	if (error)
+		disk->d_rotation_rate = DISK_RR_UNKNOWN;
 }
 
 void
@@ -1088,6 +1094,31 @@ g_raid_candelete(struct g_raid_softc *sc, struct bio *bp)
 	g_handleattr(bp, "GEOM::candelete", &val, sizeof(val));
 }
 
+static void
+g_raid_rotation_rate(struct g_raid_softc *sc, struct bio *bp)
+{
+	struct g_raid_volume *vol;
+	struct g_raid_subdisk *sd;
+	bool first = true;
+	uint16_t rr = DISK_RR_UNKNOWN;
+	int i;
+
+	vol = bp->bio_to->private;
+	for (i = 0; i < vol->v_disks_count; i++) {
+		sd = &vol->v_subdisks[i];
+		if (sd->sd_state == G_RAID_SUBDISK_S_NONE)
+			continue;
+		if (first)
+			rr = sd->sd_disk->d_rotation_rate;
+		else if (rr != sd->sd_disk->d_rotation_rate) {
+			rr = DISK_RR_UNKNOWN;
+			break;
+		}
+		first = false;
+	}
+	g_handleattr(bp, "GEOM::rotation_rate", &rr, sizeof(rr));
+}
+
 static void
 g_raid_start(struct bio *bp)
 {
@@ -1115,6 +1146,8 @@ g_raid_start(struct bio *bp)
 			g_raid_candelete(sc, bp);
 		else if (!strcmp(bp->bio_attribute, "GEOM::kerneldump"))
 			g_raid_kerneldump(sc, bp);
+		else if (!strcmp(bp->bio_attribute, "GEOM::rotation_rate"))
+			g_raid_rotation_rate(sc, bp);
 		else
 			g_io_deliver(bp, EOPNOTSUPP);
 		return;
diff --git a/sys/geom/raid/g_raid.h b/sys/geom/raid/g_raid.h
index d155c72711ae..d4c6937c5968 100644
--- a/sys/geom/raid/g_raid.h
+++ b/sys/geom/raid/g_raid.h
@@ -128,6 +128,7 @@ struct g_raid_disk {
 	struct g_consumer	*d_consumer;	/* GEOM disk consumer. */
 	void			*d_md_data;	/* Disk's metadata storage. */
 	int			 d_candelete;	/* BIO_DELETE supported. */
+	uint16_t		 d_rotation_rate;/* Disk's rotation rate. */
 	uint64_t		 d_flags;	/* Additional flags. */
 	u_int			 d_state;	/* Disk state. */
 	u_int			 d_load;	/* Disk average load. */