From 2bb93dd84d3ed53802f074edcd813413bb3ba33f Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Fri, 14 Apr 2017 18:11:53 +0000 Subject: [PATCH 1/2] 7659 Missing thread_exit() in dmu_send.c illumos/illumos-gate@f2c1e9bc48e4e20e8e9bd56203a75ff2e219b345 https://github.com/illumos/illumos-gate/commit/f2c1e9bc48e4e20e8e9bd56203a75ff2e219b345 https://www.illumos.org/issues/7659 Two threads send_traverse_thread() and receive_writer_thread() should end with thread_exit(); Mostly a cosmetic issue under IllumOS. https://github.com/openzfs/openzfs/pull/252 Reviewed by: Paul Dagnelie Reviewed by: Matt Ahrens Approved by: Richard Lowe Author: Jorgen Lundman --- uts/common/fs/zfs/dmu_send.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/uts/common/fs/zfs/dmu_send.c b/uts/common/fs/zfs/dmu_send.c index 01a4514a3316..e0abf7dbaca3 100644 --- a/uts/common/fs/zfs/dmu_send.c +++ b/uts/common/fs/zfs/dmu_send.c @@ -576,6 +576,7 @@ send_traverse_thread(void *arg) data = kmem_zalloc(sizeof (*data), KM_SLEEP); data->eos_marker = B_TRUE; bqueue_enqueue(&st_arg->q, data, 1); + thread_exit(); } /* @@ -2815,6 +2816,7 @@ receive_writer_thread(void *arg) rwa->done = B_TRUE; cv_signal(&rwa->cv); mutex_exit(&rwa->mutex); + thread_exit(); } static int From 768d3677f6980d037db88440f102c302a7ee267c Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Fri, 14 Apr 2017 18:13:06 +0000 Subject: [PATCH 2/2] 7743 per-vdev-zaps have no initialize path on upgrade illumos/illumos-gate@555da5111b0f2552c42d057b211aba89c9c79f6c https://github.com/illumos/illumos-gate/commit/555da5111b0f2552c42d057b211aba89c9c79f6c https://www.illumos.org/issues/7743 When loading a pool that had been created before the existance of per-vdev zaps, on a system that knows about per-vdev zaps, the per-vdev zaps will not be allocated and initialized. This appears to be because the logic that would have done so, in spa_sync_config_object(), is not reached under normal operation. It is only reached if spa_config_dirty_list is non-empty. The fix is to add another `AVZ_ACTION_` enum that will allow this code to be reached when we detect that we're loading an old pool, even when there are no dirty configs. Reviewed by: Matt Ahrens Reviewed by: Pavel Zakharov Reviewed by: George Wilson Reviewed by: Don Brady Approved by: Robert Mustacchi Author: Paul Dagnelie --- uts/common/fs/zfs/spa.c | 11 ++++++++--- uts/common/fs/zfs/sys/spa_impl.h | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/uts/common/fs/zfs/spa.c b/uts/common/fs/zfs/spa.c index bb1ecaa4cc4a..5764d47c3309 100644 --- a/uts/common/fs/zfs/spa.c +++ b/uts/common/fs/zfs/spa.c @@ -2657,10 +2657,14 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config, error = spa_dir_prop(spa, DMU_POOL_VDEV_ZAP_MAP, &spa->spa_all_vdev_zaps); - if (error != ENOENT && error != 0) { + if (error == ENOENT) { + VERIFY(!nvlist_exists(mos_config, + ZPOOL_CONFIG_HAS_PER_VDEV_ZAPS)); + spa->spa_avz_action = AVZ_ACTION_INITIALIZE; + ASSERT0(vdev_count_verify_zaps(spa->spa_root_vdev)); + } else if (error != 0) { return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO)); - } else if (error == 0 && !nvlist_exists(mos_config, - ZPOOL_CONFIG_HAS_PER_VDEV_ZAPS)) { + } else if (!nvlist_exists(mos_config, ZPOOL_CONFIG_HAS_PER_VDEV_ZAPS)) { /* * An older version of ZFS overwrote the sentinel value, so * we have orphaned per-vdev ZAPs in the MOS. Defer their @@ -6156,6 +6160,7 @@ spa_sync_config_object(spa_t *spa, dmu_tx_t *tx) spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); ASSERT(spa->spa_avz_action == AVZ_ACTION_NONE || + spa->spa_avz_action == AVZ_ACTION_INITIALIZE || spa->spa_all_vdev_zaps != 0); if (spa->spa_avz_action == AVZ_ACTION_REBUILD) { diff --git a/uts/common/fs/zfs/sys/spa_impl.h b/uts/common/fs/zfs/sys/spa_impl.h index b19863c4d897..8413a843cd87 100644 --- a/uts/common/fs/zfs/sys/spa_impl.h +++ b/uts/common/fs/zfs/sys/spa_impl.h @@ -119,7 +119,8 @@ typedef struct spa_taskqs { typedef enum spa_all_vdev_zap_action { AVZ_ACTION_NONE = 0, AVZ_ACTION_DESTROY, /* Destroy all per-vdev ZAPs and the AVZ. */ - AVZ_ACTION_REBUILD /* Populate the new AVZ, see spa_avz_rebuild */ + AVZ_ACTION_REBUILD, /* Populate the new AVZ, see spa_avz_rebuild */ + AVZ_ACTION_INITIALIZE } spa_avz_action_t; struct spa {