summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorGeorge Wilson <[email protected]>2012-09-01 16:44:00 -0400
committerBrian Behlendorf <[email protected]>2012-10-03 13:59:02 -0700
commit65947351e71bec2ec5673bf0c3ad02f2c2b96b6c (patch)
tree21d30645e2e6a354ce404c09a26422fd5f2cf51d /module/zfs
parentd13524579162b35189804c357a63993be758b84c (diff)
Illumos #3129, #3130
illumos/illumos-gate@d6afdce20f8481c95471dd821bc8ec0dbde66213 Illumos changeset: 13794:7c5e0e746b2c 3129 'zpool reopen' restarts resilvers 3130 ztest failure: Assertion failed: 0 == dmu_objset_destroy(name, B_FALSE) (0x0 == 0x10) Reviewed by: Eric Schrock <[email protected]> Reviewed by: Matt Ahrens <[email protected]> Reviewed by: Christopher Siden <[email protected]> Reviewed by: Adam Leventhal <[email protected]> Approved by: Dan McDonald <[email protected]> References: https://www.illumos.org/issues/3129 https://www.illumos.org/issues/3130 Ported by: Etienne Dechamps <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #994
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/dsl_dir.c12
-rw-r--r--module/zfs/zfs_ioctl.c10
2 files changed, 17 insertions, 5 deletions
diff --git a/module/zfs/dsl_dir.c b/module/zfs/dsl_dir.c
index d615832c5..97b38d209 100644
--- a/module/zfs/dsl_dir.c
+++ b/module/zfs/dsl_dir.c
@@ -460,12 +460,14 @@ dsl_dir_destroy_check(void *arg1, void *arg2, dmu_tx_t *tx)
/*
* There should be exactly two holds, both from
* dsl_dataset_destroy: one on the dd directory, and one on its
- * head ds. Otherwise, someone is trying to lookup something
- * inside this dir while we want to destroy it. The
- * config_rwlock ensures that nobody else opens it after we
- * check.
+ * head ds. If there are more holds, then a concurrent thread is
+ * performing a lookup inside this dir while we're trying to destroy
+ * it. To minimize this possibility, we perform this check only
+ * in syncing context and fail the operation if we encounter
+ * additional holds. The dp_config_rwlock ensures that nobody else
+ * opens it after we check.
*/
- if (dmu_buf_refcount(dd->dd_dbuf) > 2)
+ if (dmu_tx_is_syncing(tx) && dmu_buf_refcount(dd->dd_dbuf) > 2)
return (EBUSY);
err = zap_count(mos, dd->dd_phys->dd_child_dir_zapobj, &count);
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
index aeac01496..c609203ea 100644
--- a/module/zfs/zfs_ioctl.c
+++ b/module/zfs/zfs_ioctl.c
@@ -4094,7 +4094,17 @@ zfs_ioc_pool_reopen(zfs_cmd_t *zc)
return (error);
spa_vdev_state_enter(spa, SCL_NONE);
+
+ /*
+ * If a resilver is already in progress then set the
+ * spa_scrub_reopen flag to B_TRUE so that we don't restart
+ * the scan as a side effect of the reopen. Otherwise, let
+ * vdev_open() decided if a resilver is required.
+ */
+ spa->spa_scrub_reopen = dsl_scan_resilvering(spa->spa_dsl_pool);
vdev_reopen(spa->spa_root_vdev);
+ spa->spa_scrub_reopen = B_FALSE;
+
(void) spa_vdev_state_exit(spa, NULL, 0);
spa_close(spa, FTAG);
return (0);