svn commit: r203504 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs

Adam McDougall mcdouga9 at egr.msu.edu
Tue Mar 16 20:21:30 UTC 2010


I think I have probably encountered this issue on two systems now,
one already has the zpool created with a workaround but the other we
are installing fresh with 8.0-rel.  Can it be MFC'ed now, hopefully
before the March 2010 snapshot isos are built?  Thanks.

On Thu, Feb 04, 2010 at 09:11:44PM +0000, Pawel Jakub Dawidek wrote:

  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 <ktouet at gmail.com>, mr
    Tested by:	mr, Baginski Darren <kickbsd at ya.ru>
    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;
   
  _______________________________________________
  svn-src-all at freebsd.org mailing list
  http://lists.freebsd.org/mailman/listinfo/svn-src-all
  To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
  


More information about the svn-src-all mailing list