diff options
author | mav <mav@FreeBSD.org> | 2012-05-03 05:32:56 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2012-05-03 05:32:56 +0000 |
commit | 6a0688c8fd793f12e94493c122206163820eeff4 (patch) | |
tree | fda456d967696df8ee3957afdb65209df7459832 /sys/geom/raid | |
parent | 62cde8b2a25544589eae9eaf2fcf961f3a58a310 (diff) | |
download | FreeBSD-src-6a0688c8fd793f12e94493c122206163820eeff4.zip FreeBSD-src-6a0688c8fd793f12e94493c122206163820eeff4.tar.gz |
Add optional -o argument to the `graid label ` to specify some metadata
format options. Use it for specifying byte order for the DDF metadata:
big-endian defined by specification and little-endian used by Adaptec.
Diffstat (limited to 'sys/geom/raid')
-rw-r--r-- | sys/geom/raid/g_raid.c | 7 | ||||
-rw-r--r-- | sys/geom/raid/g_raid.h | 3 | ||||
-rw-r--r-- | sys/geom/raid/g_raid_ctl.c | 2 | ||||
-rw-r--r-- | sys/geom/raid/g_raid_md_if.m | 19 | ||||
-rw-r--r-- | sys/geom/raid/md_ddf.c | 46 |
5 files changed, 63 insertions, 14 deletions
diff --git a/sys/geom/raid/g_raid.c b/sys/geom/raid/g_raid.c index 85074f8..7688ec3 100644 --- a/sys/geom/raid/g_raid.c +++ b/sys/geom/raid/g_raid.c @@ -2143,7 +2143,7 @@ g_raid_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name); G_RAID_DEBUG(2, "Tasting provider %s.", pp->name); - gp = g_new_geomf(mp, "mirror:taste"); + gp = g_new_geomf(mp, "raid:taste"); /* * This orphan function should be never called. */ @@ -2173,7 +2173,8 @@ g_raid_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) } int -g_raid_create_node_format(const char *format, struct g_geom **gp) +g_raid_create_node_format(const char *format, struct gctl_req *req, + struct g_geom **gp) { struct g_raid_md_class *class; struct g_raid_md_object *obj; @@ -2191,7 +2192,7 @@ g_raid_create_node_format(const char *format, struct g_geom **gp) obj = (void *)kobj_create((kobj_class_t)class, M_RAID, M_WAITOK); obj->mdo_class = class; - status = G_RAID_MD_CREATE(obj, &g_raid_class, gp); + status = G_RAID_MD_CREATE_REQ(obj, &g_raid_class, req, gp); if (status != G_RAID_MD_TASTE_NEW) kobj_delete((kobj_t)obj, M_RAID); return (status); diff --git a/sys/geom/raid/g_raid.h b/sys/geom/raid/g_raid.h index 1572320..9def96d 100644 --- a/sys/geom/raid/g_raid.h +++ b/sys/geom/raid/g_raid.h @@ -382,7 +382,8 @@ const char * g_raid_disk_state2str(int state); struct g_raid_softc * g_raid_create_node(struct g_class *mp, const char *name, struct g_raid_md_object *md); -int g_raid_create_node_format(const char *format, struct g_geom **gp); +int g_raid_create_node_format(const char *format, struct gctl_req *req, + struct g_geom **gp); struct g_raid_volume * g_raid_create_volume(struct g_raid_softc *sc, const char *name, int id); struct g_raid_disk * g_raid_create_disk(struct g_raid_softc *sc); diff --git a/sys/geom/raid/g_raid_ctl.c b/sys/geom/raid/g_raid_ctl.c index 028aa94..4d0147f 100644 --- a/sys/geom/raid/g_raid_ctl.c +++ b/sys/geom/raid/g_raid_ctl.c @@ -88,7 +88,7 @@ g_raid_ctl_label(struct gctl_req *req, struct g_class *mp) gctl_error(req, "No format recieved."); return; } - crstatus = g_raid_create_node_format(format, &geom); + crstatus = g_raid_create_node_format(format, req, &geom); if (crstatus == G_RAID_MD_TASTE_FAIL) { gctl_error(req, "Failed to create array with format '%s'.", format); diff --git a/sys/geom/raid/g_raid_md_if.m b/sys/geom/raid/g_raid_md_if.m index 05e9f66..3fcbab4 100644 --- a/sys/geom/raid/g_raid_md_if.m +++ b/sys/geom/raid/g_raid_md_if.m @@ -49,13 +49,22 @@ HEADER { # Default implementations of methods. CODE { static int - g_raid_md_create_default(struct g_raid_md_object *md) + g_raid_md_create_default(struct g_raid_md_object *md, + struct g_class *mp, struct g_geom **gp) { return (G_RAID_MD_TASTE_FAIL); } static int + g_raid_md_create_req_default(struct g_raid_md_object *md, + struct g_class *mp, struct gctl_req *req, struct g_geom **gp) + { + + return (G_RAID_MD_CREATE(md, mp, gp)); + } + + static int g_raid_md_ctl_default(struct g_raid_md_object *md, struct gctl_req *req) { @@ -95,6 +104,14 @@ METHOD int create { struct g_geom **gp; } DEFAULT g_raid_md_create_default; +# create_req() - create new node from scratch, with request argument. +METHOD int create_req { + struct g_raid_md_object *md; + struct g_class *mp; + struct gctl_req *req; + struct g_geom **gp; +} DEFAULT g_raid_md_create_req_default; + # taste() - taste disk and, if needed, create new node. METHOD int taste { struct g_raid_md_object *md; 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; |