svn commit: r188839 - in head/sys: geom geom/part sys

Marcel Moolenaar marcel at FreeBSD.org
Thu Feb 19 20:48:42 PST 2009


Author: marcel
Date: Fri Feb 20 04:48:40 2009
New Revision: 188839
URL: http://svn.freebsd.org/changeset/base/188839

Log:
  Provide compatibility symlink for logical partitions:
  1.  Extend geom_dev by having it create the symlink (i.e. call
      make_dev_alias) based on the DIOCGPROVIDERALIAS ioctl.
      In this way the functionaility is generic and thus usable
      by any geom/provider.
  2.  Have g_part handle said ioctl through the devalias method,
      so that it's under control of the scheme itself. By design
      the alias will not be created for newly added partitions.

Modified:
  head/sys/geom/geom_dev.c
  head/sys/geom/part/g_part.c
  head/sys/geom/part/g_part_ebr.c
  head/sys/geom/part/g_part_if.m
  head/sys/sys/disk.h

Modified: head/sys/geom/geom_dev.c
==============================================================================
--- head/sys/geom/geom_dev.c	Fri Feb 20 04:10:31 2009	(r188838)
+++ head/sys/geom/geom_dev.c	Fri Feb 20 04:48:40 2009	(r188839)
@@ -113,6 +113,7 @@ g_dev_taste(struct g_class *mp, struct g
 {
 	struct g_geom *gp;
 	struct g_consumer *cp;
+	char *alias;
 	int error;
 	struct cdev *dev;
 
@@ -134,6 +135,17 @@ g_dev_taste(struct g_class *mp, struct g
 	gp->softc = dev;
 	dev->si_drv1 = gp;
 	dev->si_drv2 = cp;
+
+	g_topology_unlock();
+
+	alias = g_malloc(MAXPATHLEN, M_WAITOK | M_ZERO);
+	error = (pp->geom->ioctl == NULL) ? ENODEV :
+	    pp->geom->ioctl(pp, DIOCGPROVIDERALIAS, alias, 0, curthread);
+	if (!error && alias[0] != '\0')
+		make_dev_alias(dev, "%s", alias);
+	g_free(alias);
+
+	g_topology_lock();
 	return (gp);
 }
 

Modified: head/sys/geom/part/g_part.c
==============================================================================
--- head/sys/geom/part/g_part.c	Fri Feb 20 04:10:31 2009	(r188838)
+++ head/sys/geom/part/g_part.c	Fri Feb 20 04:48:40 2009	(r188839)
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/bio.h>
+#include <sys/disk.h>
 #include <sys/diskmbr.h>
 #include <sys/endian.h>
 #include <sys/kernel.h>
@@ -87,6 +88,7 @@ static g_taste_t g_part_taste;
 
 static g_access_t g_part_access;
 static g_dumpconf_t g_part_dumpconf;
+static g_ioctl_t g_part_ioctl;
 static g_orphan_t g_part_orphan;
 static g_spoiled_t g_part_spoiled;
 static g_start_t g_part_start;
@@ -103,6 +105,7 @@ static struct g_class g_part_class = {
 	/* Geom methods. */
 	.access = g_part_access,
 	.dumpconf = g_part_dumpconf,
+	.ioctl = g_part_ioctl,
 	.orphan = g_part_orphan,
 	.spoiled = g_part_spoiled,
 	.start = g_part_start,
@@ -566,6 +569,8 @@ g_part_ctl_commit(struct gctl_req *req, 
 		return (EPERM);
 	}
 
+	g_topology_unlock();
+
 	cp = LIST_FIRST(&gp->consumer);
 	if ((table->gpt_smhead | table->gpt_smtail) != 0) {
 		pp = cp->provider;
@@ -594,6 +599,7 @@ g_part_ctl_commit(struct gctl_req *req, 
 	}
 
 	if (table->gpt_scheme == &g_part_null_scheme) {
+		g_topology_lock();
 		g_access(cp, -1, -1, -1);
 		g_part_wither(gp, ENXIO);
 		return (0);
@@ -614,10 +620,13 @@ g_part_ctl_commit(struct gctl_req *req, 
 	}
 	table->gpt_created = 0;
 	table->gpt_opened = 0;
+
+	g_topology_lock();
 	g_access(cp, -1, -1, -1);
 	return (0);
 
 fail:
+	g_topology_lock();
 	gctl_error(req, "%d", error);
 	return (error);
 }
@@ -1591,6 +1600,31 @@ g_part_dumpconf(struct sbuf *sb, const c
 	}
 }
 
+static int
+g_part_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag,
+    struct thread *td)
+{
+	struct g_geom *gp;
+	struct g_part_table *table;
+	struct g_part_entry *entry;
+	int error;
+
+	gp = pp->geom;
+	table = gp->softc;
+	entry = pp->private;
+
+	switch (cmd) {
+	case DIOCGPROVIDERALIAS:
+		error = G_PART_DEVALIAS(table, entry, data, MAXPATHLEN);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+
+	return (error);
+}
+
 static void
 g_part_orphan(struct g_consumer *cp)
 {

Modified: head/sys/geom/part/g_part_ebr.c
==============================================================================
--- head/sys/geom/part/g_part_ebr.c	Fri Feb 20 04:10:31 2009	(r188838)
+++ head/sys/geom/part/g_part_ebr.c	Fri Feb 20 04:48:40 2009	(r188839)
@@ -54,12 +54,15 @@ struct g_part_ebr_table {
 struct g_part_ebr_entry {
 	struct g_part_entry	base;
 	struct dos_partition	ent;
+	int	alias;
 };
 
 static int g_part_ebr_add(struct g_part_table *, struct g_part_entry *,
     struct g_part_parms *);
 static int g_part_ebr_create(struct g_part_table *, struct g_part_parms *);
 static int g_part_ebr_destroy(struct g_part_table *, struct g_part_parms *);
+static int g_part_ebr_devalias(struct g_part_table *, struct g_part_entry *,
+    char *, size_t);
 static void g_part_ebr_dumpconf(struct g_part_table *, struct g_part_entry *,
     struct sbuf *, const char *);
 static int g_part_ebr_dumpto(struct g_part_table *, struct g_part_entry *);
@@ -81,6 +84,7 @@ static kobj_method_t g_part_ebr_methods[
 	KOBJMETHOD(g_part_add,		g_part_ebr_add),
 	KOBJMETHOD(g_part_create,	g_part_ebr_create),
 	KOBJMETHOD(g_part_destroy,	g_part_ebr_destroy),
+	KOBJMETHOD(g_part_devalias,	g_part_ebr_devalias),
 	KOBJMETHOD(g_part_dumpconf,	g_part_ebr_dumpconf),
 	KOBJMETHOD(g_part_dumpto,	g_part_ebr_dumpto),
 	KOBJMETHOD(g_part_modify,	g_part_ebr_modify),
@@ -267,6 +271,25 @@ g_part_ebr_destroy(struct g_part_table *
 	return (0);
 }
 
+static int
+g_part_ebr_devalias(struct g_part_table *table, struct g_part_entry *baseentry,
+    char *buf, size_t bufsz)
+{
+	struct g_part_ebr_entry *entry;
+	size_t len;
+
+	entry = (struct g_part_ebr_entry *)baseentry;
+	if (entry->alias == 0)
+		return (ENOENT);
+
+	len = strlcpy(buf, table->gpt_gp->name, bufsz);
+	if (len == 0)
+		return (EINVAL);
+
+	snprintf(buf + len - 1, bufsz - len, "%d", entry->alias);
+	return (0);
+}
+
 static void
 g_part_ebr_dumpconf(struct g_part_table *table, struct g_part_entry *baseentry, 
     struct sbuf *sb, const char *indent)
@@ -413,12 +436,13 @@ g_part_ebr_read(struct g_part_table *bas
 	u_char *buf;
 	off_t ofs, msize;
 	u_int lba;
-	int error, index;
+	int alias, error, index;
 
 	pp = cp->provider;
 	table = (struct g_part_ebr_table *)basetable;
 	msize = pp->mediasize / pp->sectorsize;
 
+	alias = 5;
 	lba = 0;
 	while (1) {
 		ofs = (off_t)lba * pp->sectorsize;
@@ -445,6 +469,7 @@ g_part_ebr_read(struct g_part_table *bas
 		    pp->sectorsize;
 		entry = (struct g_part_ebr_entry *)baseentry;
 		entry->ent = ent[0];
+		entry->alias = alias++;
 
 		if (ent[1].dp_typ == 0)
 			break;

Modified: head/sys/geom/part/g_part_if.m
==============================================================================
--- head/sys/geom/part/g_part_if.m	Fri Feb 20 04:10:31 2009	(r188838)
+++ head/sys/geom/part/g_part_if.m	Fri Feb 20 04:48:40 2009	(r188839)
@@ -75,6 +75,15 @@ METHOD int destroy {
 	struct g_part_parms *gpp;
 };
 
+# devalias() - return the name (if any) to be used as an alias for
+# the device special file created for the partition entry.
+METHOD int devalias {
+	struct g_part_table *table;
+	struct g_part_entry *entry;
+	char *buf;
+	size_t bufsz;
+};
+
 # dumpconf()
 METHOD void dumpconf {
 	struct g_part_table *table;

Modified: head/sys/sys/disk.h
==============================================================================
--- head/sys/sys/disk.h	Fri Feb 20 04:10:31 2009	(r188838)
+++ head/sys/sys/disk.h	Fri Feb 20 04:48:40 2009	(r188839)
@@ -104,4 +104,10 @@ void disk_err(struct bio *bp, const char
 	 * must be at least MAXPATHLEN bytes long.
 	 */
 
+#define	DIOCGPROVIDERALIAS _IOR('d', 139, char[MAXPATHLEN])
+	/*-
+	 * Store the provider alias, if present, in a buffer. The buffer must
+	 * be at least MAXPATHLEN bytes long.
+	 */
+
 #endif /* _SYS_DISK_H_ */


More information about the svn-src-head mailing list