diff --git a/sys/geom/mirror/g_mirror.h b/sys/geom/mirror/g_mirror.h --- a/sys/geom/mirror/g_mirror.h +++ b/sys/geom/mirror/g_mirror.h @@ -139,6 +139,7 @@ u_int d_init_ndisks; /* Initial number of mirror components */ uint32_t d_init_slice; /* Initial slice size */ uint8_t d_init_balance;/* Initial balance */ + uint16_t d_rotation_rate;/* Disk's rotation rate */ uint64_t d_init_mediasize;/* Initial mediasize */ }; #define d_name d_consumer->provider->name diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -48,6 +48,7 @@ #include #include +#include #include FEATURE(geom_mirror, "GEOM mirroring support"); @@ -479,6 +480,10 @@ error = g_getattr("GEOM::candelete", disk->d_consumer, &i); if (error == 0 && i != 0) disk->d_flags |= G_MIRROR_DISK_FLAG_CANDELETE; + error = g_getattr("GEOM::rotation_rate", disk->d_consumer, + &disk->d_rotation_rate); + if (error) + disk->d_rotation_rate = DISK_RR_UNKNOWN; if (md->md_provider[0] != '\0') disk->d_flags |= G_MIRROR_DISK_FLAG_HARDCODED; disk->d_sync.ds_consumer = NULL; @@ -1147,6 +1152,27 @@ g_mirror_get_diskname(disk)); } +static void +g_mirror_rotation_rate(struct bio *bp) +{ + struct g_mirror_softc *sc; + struct g_mirror_disk *disk; + bool first = true; + uint16_t rr = DISK_RR_UNKNOWN; + + sc = bp->bio_to->private; + LIST_FOREACH(disk, &sc->sc_disks, d_next) { + 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_mirror_start(struct bio *bp) { @@ -1176,6 +1202,9 @@ } else if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) { g_mirror_kernel_dump(bp); return; + } else if (!strcmp(bp->bio_attribute, "GEOM::rotation_rate")) { + g_mirror_rotation_rate(bp); + return; } /* FALLTHROUGH */ default: