summaryrefslogtreecommitdiffstats
path: root/sys/geom/raid/md_ddf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/geom/raid/md_ddf.c')
-rw-r--r--sys/geom/raid/md_ddf.c46
1 files changed, 38 insertions, 8 deletions
diff --git a/sys/geom/raid/md_ddf.c b/sys/geom/raid/md_ddf.c
index 08d6f4b..068f7fa 100644
--- a/sys/geom/raid/md_ddf.c
+++ b/sys/geom/raid/md_ddf.c
@@ -88,6 +88,7 @@ struct g_raid_md_ddf_pervolume {
struct g_raid_md_ddf_object {
struct g_raid_md_object mdio_base;
+ u_int mdio_bigendian;
struct ddf_meta mdio_meta;
int mdio_starting;
struct callout mdio_start_co; /* STARTING state timer. */
@@ -95,7 +96,7 @@ struct g_raid_md_ddf_object {
struct root_hold_token *mdio_rootmount; /* Root mount delay token. */
};
-static g_raid_md_create_t g_raid_md_create_ddf;
+static g_raid_md_create_req_t g_raid_md_create_req_ddf;
static g_raid_md_taste_t g_raid_md_taste_ddf;
static g_raid_md_event_t g_raid_md_event_ddf;
static g_raid_md_volume_event_t g_raid_md_volume_event_ddf;
@@ -107,7 +108,7 @@ static g_raid_md_free_volume_t g_raid_md_free_volume_ddf;
static g_raid_md_free_t g_raid_md_free_ddf;
static kobj_method_t g_raid_md_ddf_methods[] = {
- KOBJMETHOD(g_raid_md_create, g_raid_md_create_ddf),
+ KOBJMETHOD(g_raid_md_create_req, g_raid_md_create_req_ddf),
KOBJMETHOD(g_raid_md_taste, g_raid_md_taste_ddf),
KOBJMETHOD(g_raid_md_event, g_raid_md_event_ddf),
KOBJMETHOD(g_raid_md_volume_event, g_raid_md_volume_event_ddf),
@@ -562,6 +563,7 @@ ddf_meta_create(struct g_raid_disk *disk, struct ddf_meta *sample)
struct timespec ts;
struct clocktime ct;
struct g_raid_md_ddf_perdisk *pd;
+ struct g_raid_md_ddf_object *mdi;
struct ddf_meta *meta;
struct ddf_pd_entry *pde;
off_t anchorlba;
@@ -572,13 +574,14 @@ ddf_meta_create(struct g_raid_disk *disk, struct ddf_meta *sample)
if (sample->hdr == NULL)
sample = NULL;
+ mdi = (struct g_raid_md_ddf_object *)disk->d_softc->sc_md;
pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
meta = &pd->pd_meta;
ss = disk->d_consumer->provider->sectorsize;
anchorlba = disk->d_consumer->provider->mediasize / ss - 1;
meta->sectorsize = ss;
- meta->bigendian = sample ? sample->bigendian : 0;
+ meta->bigendian = sample ? sample->bigendian : mdi->mdio_bigendian;
getnanotime(&ts);
clock_ts_to_ct(&ts, &ct);
@@ -2012,11 +2015,26 @@ g_raid_md_ddf_new_disk(struct g_raid_disk *disk)
}
static int
-g_raid_md_create_ddf(struct g_raid_md_object *md, struct g_class *mp,
- struct g_geom **gp)
+g_raid_md_create_req_ddf(struct g_raid_md_object *md, struct g_class *mp,
+ struct gctl_req *req, struct g_geom **gp)
{
struct g_geom *geom;
struct g_raid_softc *sc;
+ struct g_raid_md_ddf_object *mdi, *mdi1;
+ char name[16];
+ const char *fmtopt;
+ int be = 1;
+
+ mdi = (struct g_raid_md_ddf_object *)md;
+ fmtopt = gctl_get_asciiparam(req, "fmtopt");
+ if (fmtopt == NULL || strcasecmp(fmtopt, "BE") == 0)
+ be = 1;
+ else if (strcasecmp(fmtopt, "LE") == 0)
+ be = 0;
+ else {
+ gctl_error(req, "Incorrect fmtopt argument.");
+ return (G_RAID_MD_TASTE_FAIL);
+ }
/* Search for existing node. */
LIST_FOREACH(geom, &mp->geom, geom) {
@@ -2027,6 +2045,9 @@ g_raid_md_create_ddf(struct g_raid_md_object *md, struct g_class *mp,
continue;
if (sc->sc_md->mdo_class != md->mdo_class)
continue;
+ mdi1 = (struct g_raid_md_ddf_object *)sc->sc_md;
+ if (mdi1->mdio_bigendian != be)
+ continue;
break;
}
if (geom != NULL) {
@@ -2035,7 +2056,9 @@ g_raid_md_create_ddf(struct g_raid_md_object *md, struct g_class *mp,
}
/* Create new one if not found. */
- sc = g_raid_create_node(mp, "DDF", md);
+ mdi->mdio_bigendian = be;
+ snprintf(name, sizeof(name), "DDF%s", be ? "" : "-LE");
+ sc = g_raid_create_node(mp, name, md);
if (sc == NULL)
return (G_RAID_MD_TASTE_FAIL);
md->mdo_softc = sc;
@@ -2053,11 +2076,13 @@ g_raid_md_taste_ddf(struct g_raid_md_object *md, struct g_class *mp,
struct g_raid_disk *disk;
struct ddf_meta meta;
struct g_raid_md_ddf_perdisk *pd;
+ struct g_raid_md_ddf_object *mdi;
struct g_geom *geom;
- int error, result, len;
+ int error, result, len, be;
char name[16];
G_RAID_DEBUG(1, "Tasting DDF on %s", cp->provider->name);
+ mdi = (struct g_raid_md_ddf_object *)md;
pp = cp->provider;
/* Read metadata from device. */
@@ -2070,6 +2095,7 @@ g_raid_md_taste_ddf(struct g_raid_md_object *md, struct g_class *mp,
g_access(cp, -1, 0, 0);
if (error != 0)
return (G_RAID_MD_TASTE_FAIL);
+ be = meta.bigendian;
/* Metadata valid. Print it. */
g_raid_md_ddf_print(&meta);
@@ -2084,6 +2110,9 @@ g_raid_md_taste_ddf(struct g_raid_md_object *md, struct g_class *mp,
continue;
if (sc->sc_md->mdo_class != md->mdo_class)
continue;
+ mdi = (struct g_raid_md_ddf_object *)sc->sc_md;
+ if (mdi->mdio_bigendian != be)
+ continue;
break;
}
@@ -2094,7 +2123,8 @@ g_raid_md_taste_ddf(struct g_raid_md_object *md, struct g_class *mp,
} else { /* Not found matching node -- create one. */
result = G_RAID_MD_TASTE_NEW;
- snprintf(name, sizeof(name), "DDF");
+ mdi->mdio_bigendian = be;
+ snprintf(name, sizeof(name), "DDF%s", be ? "" : "-LE");
sc = g_raid_create_node(mp, name, md);
md->mdo_softc = sc;
geom = sc->sc_geom;
OpenPOWER on IntegriCloud