Skip to content

Commit d6afdce

Browse files
committed
3129 'zpool reopen' restarts resilvers
3130 ztest failure: Assertion failed: 0 == dmu_objset_destroy(name, B_FALSE) (0x0 == 0x10) Reviewed by: Eric Schrock <eric.schrock@delphix.com> Reviewed by: Matt Ahrens <matthew.ahrens@delphix.com> Reviewed by: Christopher Siden <chris.siden@delphix.com> Reviewed by: Adam Leventhal <ahl@delphix.com> Approved by: Dan McDonald <danmcd@nexenta.com>
1 parent 53d0048 commit d6afdce

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

usr/src/uts/common/fs/zfs/dsl_dir.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -456,12 +456,14 @@ dsl_dir_destroy_check(void *arg1, void *arg2, dmu_tx_t *tx)
456456
/*
457457
* There should be exactly two holds, both from
458458
* dsl_dataset_destroy: one on the dd directory, and one on its
459-
* head ds. Otherwise, someone is trying to lookup something
460-
* inside this dir while we want to destroy it. The
461-
* config_rwlock ensures that nobody else opens it after we
462-
* check.
459+
* head ds. If there are more holds, then a concurrent thread is
460+
* performing a lookup inside this dir while we're trying to destroy
461+
* it. To minimize this possibility, we perform this check only
462+
* in syncing context and fail the operation if we encounter
463+
* additional holds. The dp_config_rwlock ensures that nobody else
464+
* opens it after we check.
463465
*/
464-
if (dmu_buf_refcount(dd->dd_dbuf) > 2)
466+
if (dmu_tx_is_syncing(tx) && dmu_buf_refcount(dd->dd_dbuf) > 2)
465467
return (EBUSY);
466468

467469
err = zap_count(mos, dd->dd_phys->dd_child_dir_zapobj, &count);

usr/src/uts/common/fs/zfs/zfs_ioctl.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4335,7 +4335,17 @@ zfs_ioc_pool_reopen(zfs_cmd_t *zc)
43354335
return (error);
43364336

43374337
spa_vdev_state_enter(spa, SCL_NONE);
4338+
4339+
/*
4340+
* If a resilver is already in progress then set the
4341+
* spa_scrub_reopen flag to B_TRUE so that we don't restart
4342+
* the scan as a side effect of the reopen. Otherwise, let
4343+
* vdev_open() decided if a resilver is required.
4344+
*/
4345+
spa->spa_scrub_reopen = dsl_scan_resilvering(spa->spa_dsl_pool);
43384346
vdev_reopen(spa->spa_root_vdev);
4347+
spa->spa_scrub_reopen = B_FALSE;
4348+
43394349
(void) spa_vdev_state_exit(spa, NULL, 0);
43404350
spa_close(spa, FTAG);
43414351
return (0);

0 commit comments

Comments
 (0)