diff options
Diffstat (limited to 'sys/geom/raid/md_ddf.c')
-rw-r--r-- | sys/geom/raid/md_ddf.c | 46 |
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; |