Mercurial > illumos > illumos-gate
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 <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>
author | George Wilson <george.wilson@delphix.com> |
---|---|
date | Sat, 01 Sep 2012 16:44:00 -0400 |
parents | 10c3656ccf76 |
children | caa31a28c302 |
files | usr/src/uts/common/fs/zfs/dsl_dir.c usr/src/uts/common/fs/zfs/zfs_ioctl.c |
diffstat | 2 files changed, 17 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/dsl_dir.c Fri Aug 31 15:12:34 2012 -0500 +++ b/usr/src/uts/common/fs/zfs/dsl_dir.c Sat Sep 01 16:44:00 2012 -0400 @@ -456,12 +456,14 @@ /* * 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);
--- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c Fri Aug 31 15:12:34 2012 -0500 +++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c Sat Sep 01 16:44:00 2012 -0400 @@ -4335,7 +4335,17 @@ 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);