Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 5 Dec 2009 14:33:12 +0000 (UTC)
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r200126 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <200912051433.nB5EXCkW090560@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pjd
Date: Sat Dec  5 14:33:11 2009
New Revision: 200126
URL: http://svn.freebsd.org/changeset/base/200126

Log:
  Fix deadlock when ZVOLs are present and we are replacing dead component or
  calling scrub when pool is in a degraded state. It will try to taste ZVOLs,
  which will lead to deadlock, as ZVOL will try to acquire the same locks as
  replace/scrub is holding already.
  
  We can't simply skip provider based on their GEOM class, because ZVOL can have
  providers build on top of it and we need to skip those as well.
  
  We do it by asking for ZFS::iszvol attribute. Any ZVOL-based provider will give
  us positive answer and we have to skip those providers.
  
  This way we remove possibility to create ZFS pools on top of ZVOLs, but it is
  not very useful anyway.
  
  I believe deadlock is still possible in some very complex situations like when
  we have MD provider on top of UFS file on top of ZVOL. When we try to replace
  dead component in the pool mentioned ZVOL is based on, there might be a
  deadlock when ZFS will try to taste MD provider. There is no easy way to detect
  that, but it isn't very common.
  
  MFC after:	1 week

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.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	Sat Dec  5 14:24:22 2009	(r200125)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	Sat Dec  5 14:33:11 2009	(r200126)
@@ -293,11 +293,16 @@ vdev_geom_read_guid(struct g_consumer *c
 	uint64_t psize;
 	off_t offset, size;
 	uint64_t guid;
-	int l, len;
+	int error, l, len, iszvol;
 
 	g_topology_assert_not();
 
 	pp = cp->provider;
+	ZFS_LOG(1, "Reading guid from %s...", pp->name);
+	if (g_getattr("ZFS::iszvol", cp, &iszvol) == 0 && iszvol) {
+		ZFS_LOG(1, "Skipping ZVOL-based provider %s.", pp->name);
+		return (0);
+	}
 
 	psize = pp->mediasize;
 	psize = P2ALIGN(psize, (uint64_t)sizeof(vdev_label_t));

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c	Sat Dec  5 14:24:22 2009	(r200125)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c	Sat Dec  5 14:33:11 2009	(r200126)
@@ -335,8 +335,11 @@ zvol_start(struct bio *bp)
 		wakeup_one(&zv->zv_queue);
 		mtx_unlock(&zv->zv_queue_mtx);
 		break;
-	case BIO_DELETE:
 	case BIO_GETATTR:
+		if (g_handleattr_int(bp, "ZFS::iszvol", 1))
+			break;
+		/* FALLTHROUGH */
+	case BIO_DELETE:
 	default:
 		g_io_deliver(bp, EOPNOTSUPP);
 		break;



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