From owner-svn-src-all@FreeBSD.ORG Thu Feb 4 21:11:44 2010 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 68CB61065692; Thu, 4 Feb 2010 21:11:44 +0000 (UTC) (envelope-from pjd@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 5646F8FC12; Thu, 4 Feb 2010 21:11:44 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o14LBiCc031728; Thu, 4 Feb 2010 21:11:44 GMT (envelope-from pjd@svn.freebsd.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o14LBixZ031726; Thu, 4 Feb 2010 21:11:44 GMT (envelope-from pjd@svn.freebsd.org) Message-Id: <201002042111.o14LBixZ031726@svn.freebsd.org> From: Pawel Jakub Dawidek Date: Thu, 4 Feb 2010 21:11:44 +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: r203504 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs 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: Thu, 04 Feb 2010 21:11:44 -0000 Author: pjd Date: Thu Feb 4 21:11:44 2010 New Revision: 203504 URL: http://svn.freebsd.org/changeset/base/203504 Log: Open provider for writting when we find the right one. Opening too much providers for writing provokes huge traffic related to taste events send by GEOM on close. This can lead to various problems with opening GEOM providers that are created on top of other GEOM providers. Reorted by: Kurt Touet , mr Tested by: mr, Baginski Darren MFC after: 2 weeks Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Thu Feb 4 21:02:29 2010 (r203503) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Thu Feb 4 21:11:44 2010 (r203504) @@ -102,7 +102,7 @@ vdev_geom_orphan(struct g_consumer *cp) } static struct g_consumer * -vdev_geom_attach(struct g_provider *pp, int write) +vdev_geom_attach(struct g_provider *pp) { struct g_geom *gp; struct g_consumer *cp; @@ -126,7 +126,7 @@ vdev_geom_attach(struct g_provider *pp, g_wither_geom(gp, ENXIO); return (NULL); } - if (g_access(cp, 1, write, 1) != 0) { + if (g_access(cp, 1, 0, 1) != 0) { g_wither_geom(gp, ENXIO); return (NULL); } @@ -145,14 +145,14 @@ vdev_geom_attach(struct g_provider *pp, g_destroy_consumer(cp); return (NULL); } - if (g_access(cp, 1, write, 1) != 0) { + if (g_access(cp, 1, 0, 1) != 0) { g_detach(cp); g_destroy_consumer(cp); return (NULL); } ZFS_LOG(1, "Created consumer for %s.", pp->name); } else { - if (g_access(cp, 1, cp->acw > 0 ? 0 : write, 1) != 0) + if (g_access(cp, 1, 0, 1) != 0) return (NULL); ZFS_LOG(1, "Used existing consumer for %s.", pp->name); } @@ -342,7 +342,6 @@ vdev_geom_read_guid(struct g_consumer *c struct vdev_geom_find { uint64_t guid; - int write; struct g_consumer *cp; }; @@ -394,10 +393,10 @@ vdev_geom_attach_by_guid_event(void *arg g_detach(zcp); if (guid != ap->guid) continue; - ap->cp = vdev_geom_attach(pp, ap->write); + ap->cp = vdev_geom_attach(pp); if (ap->cp == NULL) { - printf("ZFS WARNING: Cannot open %s " - "for writting.\n", pp->name); + printf("ZFS WARNING: Unable to attach to %s.", + pp->name); continue; } goto end; @@ -411,14 +410,13 @@ end: } static struct g_consumer * -vdev_geom_attach_by_guid(uint64_t guid, int write) +vdev_geom_attach_by_guid(uint64_t guid) { struct vdev_geom_find *ap; struct g_consumer *cp; ap = kmem_zalloc(sizeof(*ap), KM_SLEEP); ap->guid = guid; - ap->write = write; g_waitfor_event(vdev_geom_attach_by_guid_event, ap, M_WAITOK, NULL); cp = ap->cp; kmem_free(ap, sizeof(*ap)); @@ -433,7 +431,7 @@ vdev_geom_open_by_guid(vdev_t *vd) size_t len; ZFS_LOG(1, "Searching by guid [%ju].", (uintmax_t)vd->vdev_guid); - cp = vdev_geom_attach_by_guid(vd->vdev_guid, !!(spa_mode & FWRITE)); + cp = vdev_geom_attach_by_guid(vd->vdev_guid); if (cp != NULL) { len = strlen(cp->provider->name) + strlen("/dev/") + 1; buf = kmem_alloc(len, KM_SLEEP); @@ -464,7 +462,7 @@ vdev_geom_open_by_path(vdev_t *vd, int c pp = g_provider_by_name(vd->vdev_path + sizeof("/dev/") - 1); if (pp != NULL) { ZFS_LOG(1, "Found provider by name %s.", vd->vdev_path); - cp = vdev_geom_attach(pp, !!(spa_mode & FWRITE)); + cp = vdev_geom_attach(pp); if (cp != NULL && check_guid) { g_topology_unlock(); guid = vdev_geom_read_guid(cp); @@ -492,7 +490,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psi vdev_geom_ctx_t *ctx; struct g_provider *pp; struct g_consumer *cp; - int owned; + int error, owned; /* * We must have a pathname, and it must be absolute. @@ -506,6 +504,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psi if ((owned = mtx_owned(&Giant))) mtx_unlock(&Giant); + error = 0; cp = vdev_geom_open_by_path(vd, 1); if (cp == NULL) { /* @@ -519,13 +518,24 @@ vdev_geom_open(vdev_t *vd, uint64_t *psi cp = vdev_geom_open_by_path(vd, 0); if (cp == NULL) { ZFS_LOG(1, "Provider %s not found.", vd->vdev_path); - vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; - if (owned) - mtx_lock(&Giant); - return (EACCES); + error = ENOENT; + } else if (cp->acw == 0 && (spa_mode & FWRITE) != 0) { + g_topology_lock(); + error = g_access(cp, 0, 1, 0); + if (error != 0) { + printf("ZFS WARNING: Unable to open %s for writing (error=%d).", + vd->vdev_path, error); + vdev_geom_detach(cp, 0); + cp = NULL; + } + g_topology_unlock(); } if (owned) mtx_lock(&Giant); + if (cp == NULL) { + vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; + return (error); + } cp->private = vd;