svn commit: r234940 - in head: sbin/geom/class/raid sys/geom/raid

Alexander Motin mav at FreeBSD.org
Thu May 3 05:32:57 UTC 2012


Author: mav
Date: Thu May  3 05:32:56 2012
New Revision: 234940
URL: http://svn.freebsd.org/changeset/base/234940

Log:
  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.

Modified:
  head/sbin/geom/class/raid/geom_raid.c
  head/sbin/geom/class/raid/graid.8
  head/sys/geom/raid/g_raid.c
  head/sys/geom/raid/g_raid.h
  head/sys/geom/raid/g_raid_ctl.c
  head/sys/geom/raid/g_raid_md_if.m
  head/sys/geom/raid/md_ddf.c

Modified: head/sbin/geom/class/raid/geom_raid.c
==============================================================================
--- head/sbin/geom/class/raid/geom_raid.c	Thu May  3 05:04:37 2012	(r234939)
+++ head/sbin/geom/class/raid/geom_raid.c	Thu May  3 05:32:56 2012	(r234940)
@@ -48,11 +48,12 @@ struct g_command class_commands[] = {
 	{ "label", G_FLAG_VERBOSE, NULL,
 	    {
 		{ 'f', "force", NULL, G_TYPE_BOOL },
+		{ 'o', "fmtopt", G_VAL_OPTIONAL, G_TYPE_STRING },
 		{ 'S', "size", G_VAL_OPTIONAL, G_TYPE_NUMBER },
 		{ 's', "strip", G_VAL_OPTIONAL, G_TYPE_NUMBER },
 		G_OPT_SENTINEL
 	    },
-	    "[-fv] [-S size] [-s stripsize] format label level prov ..."
+	    "[-fv] [-o fmtopt] [-S size] [-s stripsize] format label level prov ..."
 	},
 	{ "add", G_FLAG_VERBOSE, NULL,
 	    {

Modified: head/sbin/geom/class/raid/graid.8
==============================================================================
--- head/sbin/geom/class/raid/graid.8	Thu May  3 05:04:37 2012	(r234939)
+++ head/sbin/geom/class/raid/graid.8	Thu May  3 05:32:56 2012	(r234940)
@@ -34,6 +34,7 @@
 .Nm
 .Cm label
 .Op Fl f
+.Op Fl o Ar fmtopt
 .Op Fl S Ar size
 .Op Fl s Ar strip
 .Ar format
@@ -119,6 +120,8 @@ Additional options include:
 .It Fl f
 Enforce specified configuration creation if it is officially unsupported,
 but technically can be created.
+.It Fl o Ar fmtopt
+Specifies metadata format options.
 .It Fl S Ar size
 Use
 .Ar size
@@ -205,14 +208,18 @@ The format defined by the SNIA Common RA
 Used by some Adaptec RAID BIOSes and some hardware RAID controllers.
 Because of high format flexibility different implementations support
 different set of features and have different on-disk metadata layouts.
-To provide compatibility, the GEOM RAID class mimics capabilities and
-metadata layout of the first detected DDF array.
+To provide compatibility, the GEOM RAID class mimics capabilities
+of the first detected DDF array.
 Respecting that, it may support different number of disks per volume,
 volumes per array, partitions per disk, etc.
 The following configurations are supported: RAID0 (2+ disks), RAID1 (2+ disks),
 RAID1E (3+ disks), RAID3 (3+ disks), RAID4 (3+ disks), RAID5 (3+ disks),
 RAID5E (4+ disks), RAID5EE (4+ disks), RAID5R (3+ disks), RAID6 (4+ disks),
 RAIDMDF (5+ disks), RAID10 (4+ disks), SINGLE (1 disk), CONCAT (2+ disks).
+.Pp
+Format supports two options "BE" and "LE", that mean big-endian byte order
+defined by specification (default) and little-endian used by some Adaptec
+controllers.
 .It Intel
 The format used by Intel RAID BIOS.
 Supports up to two volumes per array.

Modified: head/sys/geom/raid/g_raid.c
==============================================================================
--- head/sys/geom/raid/g_raid.c	Thu May  3 05:04:37 2012	(r234939)
+++ head/sys/geom/raid/g_raid.c	Thu May  3 05:32:56 2012	(r234940)
@@ -2143,7 +2143,7 @@ g_raid_taste(struct g_class *mp, struct 
 	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 
 }
 
 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 *fo
 	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);

Modified: head/sys/geom/raid/g_raid.h
==============================================================================
--- head/sys/geom/raid/g_raid.h	Thu May  3 05:04:37 2012	(r234939)
+++ head/sys/geom/raid/g_raid.h	Thu May  3 05:32:56 2012	(r234940)
@@ -382,7 +382,8 @@ const char * g_raid_disk_state2str(int s
 
 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);

Modified: head/sys/geom/raid/g_raid_ctl.c
==============================================================================
--- head/sys/geom/raid/g_raid_ctl.c	Thu May  3 05:04:37 2012	(r234939)
+++ head/sys/geom/raid/g_raid_ctl.c	Thu May  3 05:32:56 2012	(r234940)
@@ -88,7 +88,7 @@ g_raid_ctl_label(struct gctl_req *req, s
 		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);

Modified: head/sys/geom/raid/g_raid_md_if.m
==============================================================================
--- head/sys/geom/raid/g_raid_md_if.m	Thu May  3 05:04:37 2012	(r234939)
+++ head/sys/geom/raid/g_raid_md_if.m	Thu May  3 05:32:56 2012	(r234940)
@@ -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;

Modified: head/sys/geom/raid/md_ddf.c
==============================================================================
--- head/sys/geom/raid/md_ddf.c	Thu May  3 05:04:37 2012	(r234939)
+++ head/sys/geom/raid/md_ddf.c	Thu May  3 05:32:56 2012	(r234940)
@@ -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
 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 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
 	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_dis
 }
 
 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_ob
 			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_ob
 	}
 
 	/* 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_obj
 	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_obj
 	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_obj
 			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_obj
 
 	} 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;


More information about the svn-src-head mailing list