6776104 "zfs import" deadlock between spa_unload() and spa_async_thread()
authorJeff Bonwick <Jeff.Bonwick@Sun.COM>
Thu, 14 May 2009 19:10:07 -0700
changeset 9630 e25a03f552e0
parent 9629 661d42fb05a1
child 9631 dad26a941f58
6776104 "zfs import" deadlock between spa_unload() and spa_async_thread()
usr/src/uts/common/fs/zfs/spa.c
--- a/usr/src/uts/common/fs/zfs/spa.c	Thu May 14 14:25:38 2009 -0400
+++ b/usr/src/uts/common/fs/zfs/spa.c	Thu May 14 19:10:07 2009 -0700
@@ -338,6 +338,11 @@
 			break;
 
 		case ZPOOL_PROP_BOOTFS:
+			/*
+			 * If the pool version is less than SPA_VERSION_BOOTFS,
+			 * or the pool is still being created (version == 0),
+			 * the bootfs property cannot be set.
+			 */
 			if (spa_version(spa) < SPA_VERSION_BOOTFS) {
 				error = ENOTSUP;
 				break;
@@ -641,7 +646,7 @@
 	ASSERT(spa->spa_sync_on == B_FALSE);
 	ASSERT(spa->spa_dsl_pool == NULL);
 	ASSERT(spa->spa_root_vdev == NULL);
-
+	ASSERT(spa->spa_async_zio_root == NULL);
 	ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED);
 
 	txg_list_destroy(&spa->spa_vdev_txg_list);
@@ -1175,10 +1180,8 @@
 	/*
 	 * Create "The Godfather" zio to hold all async IOs
 	 */
-	if (spa->spa_async_zio_root == NULL)
-		spa->spa_async_zio_root = zio_root(spa, NULL, NULL,
-		    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE |
-		    ZIO_FLAG_GODFATHER);
+	spa->spa_async_zio_root = zio_root(spa, NULL, NULL,
+	    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE | ZIO_FLAG_GODFATHER);
 
 	/*
 	 * Parse the configuration into a vdev tree.  We explicitly set the
@@ -2085,7 +2088,6 @@
 	spa->spa_uberblock.ub_txg = txg - 1;
 
 	if (props && (error = spa_prop_validate(spa, props))) {
-		spa_unload(spa);
 		spa_deactivate(spa);
 		spa_remove(spa);
 		mutex_exit(&spa_namespace_lock);
@@ -2102,10 +2104,8 @@
 	/*
 	 * Create "The Godfather" zio to hold all async IOs
 	 */
-	if (spa->spa_async_zio_root == NULL)
-		spa->spa_async_zio_root = zio_root(spa, NULL, NULL,
-		    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE |
-		    ZIO_FLAG_GODFATHER);
+	spa->spa_async_zio_root = zio_root(spa, NULL, NULL,
+	    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE | ZIO_FLAG_GODFATHER);
 
 	/*
 	 * Create the root vdev.
@@ -2541,6 +2541,11 @@
 	spa_activate(spa, spa_mode_global);
 
 	/*
+	 * Don't start async tasks until we know everything is healthy.
+	 */
+	spa_async_suspend(spa);
+
+	/*
 	 * Pass off the heavy lifting to spa_load().  Pass TRUE for mosconfig
 	 * because the user-supplied config is actually the one to trust when
 	 * doing an import.
@@ -2585,6 +2590,8 @@
 		return (error);
 	}
 
+	spa_async_resume(spa);
+
 	/*
 	 * Override any spares and level 2 cache devices as specified by
 	 * the user, as these may have correct device names/devids, etc.