From owner-svn-src-projects@FreeBSD.ORG Tue Aug 16 22:33:06 2011 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 56F73106566B; Tue, 16 Aug 2011 22:33:06 +0000 (UTC) (envelope-from gibbs@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 45AC08FC13; Tue, 16 Aug 2011 22:33:06 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p7GMX6kZ076070; Tue, 16 Aug 2011 22:33:06 GMT (envelope-from gibbs@svn.freebsd.org) Received: (from gibbs@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p7GMX6OD076068; Tue, 16 Aug 2011 22:33:06 GMT (envelope-from gibbs@svn.freebsd.org) Message-Id: <201108162233.p7GMX6OD076068@svn.freebsd.org> From: "Justin T. Gibbs" Date: Tue, 16 Aug 2011 22:33:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r224921 - projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Aug 2011 22:33:06 -0000 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); }