The branch main has been updated by mav: URL: https://cgit.FreeBSD.org/src/commit/?id=78376b16a4ba1eed0f804c493e2c715ccb57b165
commit 78376b16a4ba1eed0f804c493e2c715ccb57b165 Author: Alexander Motin <[email protected]> AuthorDate: 2026-08-26 00:14:11 +0000 Commit: Alexander Motin <[email protected]> CommitDate: 2026-08-26 00:14:11 +0000 gconcat: Add rotation rate support If all member devices report the same rotation rate, pass it up. --- sys/geom/concat/g_concat.c | 41 ++++++++++++++++++++++++++++++++++++++++- sys/geom/concat/g_concat.h | 1 + 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/sys/geom/concat/g_concat.c b/sys/geom/concat/g_concat.c index 5461c6dd73d3..8f39eeff5ce2 100644 --- a/sys/geom/concat/g_concat.c +++ b/sys/geom/concat/g_concat.c @@ -39,6 +39,7 @@ #include <sys/malloc.h> #include <geom/geom.h> #include <geom/geom_dbg.h> +#include <geom/geom_disk.h> #include <geom/concat/g_concat.h> FEATURE(geom_concat, "GEOM concatenation support"); @@ -228,6 +229,30 @@ g_concat_candelete(struct bio *bp) g_handleattr(bp, "GEOM::candelete", &val, sizeof(val)); } +static void +g_concat_rotation_rate(struct bio *bp) +{ + struct g_concat_softc *sc; + struct g_concat_disk *disk; + uint16_t rr = DISK_RR_UNKNOWN; + bool first = true; + + sc = bp->bio_to->geom->softc; + sx_assert(&sc->sc_disks_lock, SX_LOCKED); + TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { + if (disk->d_removed) + 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_concat_kernel_dump(struct bio *bp) { @@ -360,6 +385,10 @@ g_concat_start(struct bio *bp) } else if (strcmp("GEOM::candelete", bp->bio_attribute) == 0) { g_concat_candelete(bp); goto end; + } else if (strcmp("GEOM::rotation_rate", + bp->bio_attribute) == 0) { + g_concat_rotation_rate(bp); + goto end; } /* To which provider it should be delivered? */ /* FALLTHROUGH */ @@ -465,6 +494,10 @@ g_concat_check_and_run(struct g_concat_softc *sc) &disk->d_candelete); if (error != 0) disk->d_candelete = 0; + error = g_getattr("GEOM::rotation_rate", + disk->d_consumer, &disk->d_rotation_rate); + if (error != 0) + disk->d_rotation_rate = DISK_RR_UNKNOWN; (void)g_access(disk->d_consumer, -1, 0, 0); } else G_CONCAT_DEBUG(1, "Failed to access disk %s, error %d.", @@ -1060,7 +1093,8 @@ g_concat_ctl_append(struct gctl_req *req, struct g_class *mp) struct g_concat_disk *disk; int *nargs, *hardcode; int error; - int disk_candelete; + int disk_candelete = 0; + uint16_t disk_rotation_rate = DISK_RR_UNKNOWN; g_topology_assert(); @@ -1141,6 +1175,10 @@ g_concat_ctl_append(struct gctl_req *req, struct g_class *mp) error = g_getattr("GEOM::candelete", cp, &disk_candelete); if (error != 0) disk_candelete = 0; + error = g_getattr("GEOM::rotation_rate", cp, + &disk_rotation_rate); + if (error != 0) + disk_rotation_rate = DISK_RR_UNKNOWN; (void)g_access(cp, -1, 0, 0); } else G_CONCAT_DEBUG(1, "Failed to access disk %s, error %d.", name, error); @@ -1162,6 +1200,7 @@ g_concat_ctl_append(struct gctl_req *req, struct g_class *mp) disk->d_start = TAILQ_LAST(&sc->sc_disks, g_concat_disks)->d_end; disk->d_end = disk->d_start + cp->provider->mediasize; disk->d_candelete = disk_candelete; + disk->d_rotation_rate = disk_rotation_rate; disk->d_removed = 0; disk->d_hardcoded = *hardcode; cp->private = disk; diff --git a/sys/geom/concat/g_concat.h b/sys/geom/concat/g_concat.h index 68bfe40ee6a1..702a06c054e0 100644 --- a/sys/geom/concat/g_concat.h +++ b/sys/geom/concat/g_concat.h @@ -59,6 +59,7 @@ struct g_concat_disk { off_t d_start; off_t d_end; int d_candelete; + uint16_t d_rotation_rate; int d_removed; bool d_hardcoded; };
