Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Aug 2011 22:33:06 +0000 (UTC)
From:      "Justin T. Gibbs" <gibbs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r224921 - projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201108162233.p7GMX6OD076068@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gibbs
Date: Tue Aug 16 22:33:05 2011
New Revision: 224921
URL: http://svn.freebsd.org/changeset/base/224921

Log:
  sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c:
  	Subscribe to attribute change notifications and update
  	vdev physical path information (in core and on disk) when
  	a GEOM::physpath event indicates they have changed.
  
  Sponsored by:	Spectra Logic Corporation

Modified:
  projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c

Modified: projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
==============================================================================
--- projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	Tue Aug 16 22:20:45 2011	(r224920)
+++ projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	Tue Aug 16 22:33:05 2011	(r224921)
@@ -88,6 +88,59 @@ vdev_geom_orphan(struct g_consumer *cp)
 	spa_async_request(vd->vdev_spa, SPA_ASYNC_REMOVE);
 }
 
+static void
+vdev_geom_attrchanged(struct g_consumer *cp, const char *attr)
+{
+	vdev_t *vd;
+	spa_t *spa;
+	char *physpath;
+	int error, physpath_len;
+
+	g_topology_assert();
+
+	if (strcmp(attr, "GEOM::physpath") != 0)
+		return;
+
+	if (g_access(cp, 1, 0, 0) != 0)
+		return;
+
+	/*
+	 * Record/Update physical path information for this device.
+	 */
+	vd = cp->private;
+	spa = vd->vdev_spa;
+	physpath_len = MAXPATHLEN;
+	physpath = g_malloc(physpath_len, M_WAITOK|M_ZERO);
+	error = g_io_getattr("GEOM::physpath", cp, &physpath_len, physpath);
+	g_access(cp, -1, 0, 0);
+	if (error == 0) {
+		char *old_physpath;
+
+		old_physpath = vd->vdev_physpath;
+		vd->vdev_physpath = spa_strdup(physpath);
+		spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
+
+		if (old_physpath != NULL) {
+			int held_lock;
+
+			held_lock = spa_config_held(spa, SCL_STATE, RW_WRITER);
+			if (held_lock == 0) {
+				g_topology_unlock();
+				spa_config_enter(spa, SCL_STATE, FTAG,
+				    RW_WRITER);
+			}
+
+			spa_strfree(old_physpath);
+
+			if (held_lock == 0) {
+				spa_config_exit(spa, SCL_STATE, FTAG);
+				g_topology_lock();
+			}
+		}
+	}
+	g_free(physpath);
+}
+
 static struct g_consumer *
 vdev_geom_attach(struct g_provider *pp, vdev_t *vd)
 {
@@ -108,6 +161,7 @@ vdev_geom_attach(struct g_provider *pp, 
 	if (gp == NULL) {
 		gp = g_new_geomf(&zfs_vdev_class, "zfs::vdev");
 		gp->orphan = vdev_geom_orphan;
+		gp->attrchanged = vdev_geom_attrchanged;
 		cp = g_new_consumer(gp);
 		if (g_attach(cp, pp) != 0) {
 			g_wither_geom(gp, ENXIO);
@@ -144,7 +198,12 @@ vdev_geom_attach(struct g_provider *pp, 
 			ZFS_LOG(1, "Used existing consumer for %s.", pp->name);
 		}
 	}
+
 	cp->private = vd;
+
+	/* Fetch initial physical path information for this device. */
+	vdev_geom_attrchanged(cp, "GEOM::physpath");
+	
 	return (cp);
 }
 
@@ -521,9 +580,8 @@ vdev_geom_open(vdev_t *vd, uint64_t *psi
 		vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
 		return (error);
 	}
-
-	vd->vdev_tsd = cp;
 	pp = cp->provider;
+	vd->vdev_tsd = cp;
 
 	/*
 	 * Determine the actual size of the device.
@@ -541,12 +599,6 @@ vdev_geom_open(vdev_t *vd, uint64_t *psi
 	 */
 	vd->vdev_nowritecache = B_FALSE;
 
-	if (vd->vdev_physpath != NULL)
-		spa_strfree(vd->vdev_physpath);
-	bufsize = sizeof("/dev/") + strlen(pp->name);
-	vd->vdev_physpath = kmem_alloc(bufsize, KM_SLEEP);
-	snprintf(vd->vdev_physpath, bufsize, "/dev/%s", pp->name);
-
 	return (0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108162233.p7GMX6OD076068>