diff options
author | George Wilson <[email protected]> | 2012-09-01 16:44:00 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2012-10-03 13:59:02 -0700 |
commit | 65947351e71bec2ec5673bf0c3ad02f2c2b96b6c (patch) | |
tree | 21d30645e2e6a354ce404c09a26422fd5f2cf51d /module/zfs/dsl_dir.c | |
parent | d13524579162b35189804c357a63993be758b84c (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/dsl_dir.c')
-rw-r--r-- | module/zfs/dsl_dir.c | 12 |
1 files changed, 7 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); |