Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 17 Oct 2012 11:28:21 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r241634 - stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201210171128.q9HBSL1r059877@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Wed Oct 17 11:28:21 2012
New Revision: 241634
URL: http://svn.freebsd.org/changeset/base/241634

Log:
  MFC r240831: zfs: allow a zvol to be used as a pool vdev, again

Modified:
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c	Wed Oct 17 11:26:48 2012	(r241633)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c	Wed Oct 17 11:28:21 2012	(r241634)
@@ -874,27 +874,36 @@ zvol_open(struct g_provider *pp, int fla
 {
 	zvol_state_t *zv;
 	int err = 0;
+	boolean_t locked = B_FALSE;
 
-	if (MUTEX_HELD(&spa_namespace_lock)) {
-		/*
-		 * If the spa_namespace_lock is being held, it means that ZFS
-		 * is trying to open ZVOL as its VDEV. This is not supported.
-		 */
-		return (EOPNOTSUPP);
+	/*
+	 * Protect against recursively entering spa_namespace_lock
+	 * when spa_open() is used for a pool on a (local) ZVOL(s).
+	 * This is needed since we replaced upstream zfsdev_state_lock
+	 * with spa_namespace_lock in the ZVOL code.
+	 * We are using the same trick as spa_open().
+	 * Note that calls in zvol_first_open which need to resolve
+	 * pool name to a spa object will enter spa_open()
+	 * recursively, but that function already has all the
+	 * necessary protection.
+	 */
+	if (!MUTEX_HELD(&spa_namespace_lock)) {
+		mutex_enter(&spa_namespace_lock);
+		locked = B_TRUE;
 	}
 
-	mutex_enter(&spa_namespace_lock);
-
 	zv = pp->private;
 	if (zv == NULL) {
-		mutex_exit(&spa_namespace_lock);
+		if (locked)
+			mutex_exit(&spa_namespace_lock);
 		return (ENXIO);
 	}
 
 	if (zv->zv_total_opens == 0)
 		err = zvol_first_open(zv);
 	if (err) {
-		mutex_exit(&spa_namespace_lock);
+		if (locked)
+			mutex_exit(&spa_namespace_lock);
 		return (err);
 	}
 	if ((flag & FWRITE) && (zv->zv_flags & ZVOL_RDONLY)) {
@@ -916,13 +925,15 @@ zvol_open(struct g_provider *pp, int fla
 #endif
 
 	zv->zv_total_opens += count;
-	mutex_exit(&spa_namespace_lock);
+	if (locked)
+		mutex_exit(&spa_namespace_lock);
 
 	return (err);
 out:
 	if (zv->zv_total_opens == 0)
 		zvol_last_close(zv);
-	mutex_exit(&spa_namespace_lock);
+	if (locked)
+		mutex_exit(&spa_namespace_lock);
 	return (err);
 }
 
@@ -932,12 +943,18 @@ zvol_close(struct g_provider *pp, int fl
 {
 	zvol_state_t *zv;
 	int error = 0;
+	boolean_t locked = B_FALSE;
 
-	mutex_enter(&spa_namespace_lock);
+	/* See comment in zvol_open(). */
+	if (!MUTEX_HELD(&spa_namespace_lock)) {
+		mutex_enter(&spa_namespace_lock);
+		locked = B_TRUE;
+	}
 
 	zv = pp->private;
 	if (zv == NULL) {
-		mutex_exit(&spa_namespace_lock);
+		if (locked)
+			mutex_exit(&spa_namespace_lock);
 		return (ENXIO);
 	}
 
@@ -960,7 +977,8 @@ zvol_close(struct g_provider *pp, int fl
 	if (zv->zv_total_opens == 0)
 		zvol_last_close(zv);
 
-	mutex_exit(&spa_namespace_lock);
+	if (locked)
+		mutex_exit(&spa_namespace_lock);
 	return (error);
 }
 



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