summaryrefslogtreecommitdiffstats
path: root/sys/geom/raid
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2012-05-03 05:32:56 +0000
committermav <mav@FreeBSD.org>2012-05-03 05:32:56 +0000
commit6a0688c8fd793f12e94493c122206163820eeff4 (patch)
treefda456d967696df8ee3957afdb65209df7459832 /sys/geom/raid
parent62cde8b2a25544589eae9eaf2fcf961f3a58a310 (diff)
downloadFreeBSD-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.c7
-rw-r--r--sys/geom/raid/g_raid.h3
-rw-r--r--sys/geom/raid/g_raid_ctl.c2
-rw-r--r--sys/geom/raid/g_raid_md_if.m19
-rw-r--r--sys/geom/raid/md_ddf.c46
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;
OpenPOWER on IntegriCloud