Implement GEOM::rotation_rate for gmirror

If all of the mirror's children have the same rotation rate, report
that.  But if they have mixed rotation rates, or if any child has an
unknown rotation rate, report "Unknown".

MFC after:	2 weeks
Sponsored by:	Axcient
Reviewed by:	imp
Differential Revision: https://reviews.freebsd.org/D39458
This commit is contained in:
Alan Somers 2023-04-07 10:07:50 -06:00
parent 38594ff9c0
commit 9309a460b2
2 changed files with 30 additions and 0 deletions

View file

@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <geom/geom.h>
#include <geom/geom_dbg.h>
#include <geom/geom_disk.h>
#include <geom/mirror/g_mirror.h>
FEATURE(geom_mirror, "GEOM mirroring support");
@ -479,6 +480,10 @@ g_mirror_init_disk(struct g_mirror_softc *sc, struct g_provider *pp,
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_kernel_dump(struct bio *bp)
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 @@ g_mirror_start(struct bio *bp)
} 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:

View file

@ -139,6 +139,7 @@ struct g_mirror_disk {
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