From owner-svn-src-all@FreeBSD.ORG Fri Feb 20 04:48:41 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 611A1106564A; Fri, 20 Feb 2009 04:48:41 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4EEF98FC08; Fri, 20 Feb 2009 04:48:41 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n1K4mfg2016924; Fri, 20 Feb 2009 04:48:41 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n1K4mfYW016919; Fri, 20 Feb 2009 04:48:41 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <200902200448.n1K4mfYW016919@svn.freebsd.org> From: Marcel Moolenaar Date: Fri, 20 Feb 2009 04:48:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r188839 - in head/sys: geom geom/part sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Feb 2009 04:48:42 -0000 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 #include +#include #include #include #include @@ -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_ */