From 3808032489f28c1f36b39c9a3274d5f4b6f9638a Mon Sep 17 00:00:00 2001 From: Matthew Ahrens Date: Fri, 4 Sep 2020 10:29:39 -0700 Subject: [PATCH] nowait synctask must succeed If a `zfs_space_check_t` other than `ZFS_SPACE_CHECK_NONE` is used with `dsl_sync_task_nowait()`, the sync task may fail due to ENOSPC. However, there is no way to notice or communicate this failure, so it's extremely difficult to use this functionality correctly, and in fact almost all callers use `ZFS_SPACE_CHECK_NONE`. This commit removes the `zfs_space_check_t` argument from `dsl_sync_task_nowait()`, and always uses `ZFS_SPACE_CHECK_NONE`. Reviewed-by: Brian Behlendorf Signed-off-by: Matthew Ahrens Closes #10855 --- include/sys/dsl_synctask.h | 4 ++-- module/zfs/dmu_redact.c | 3 +-- module/zfs/dsl_synctask.c | 16 ++++++---------- module/zfs/spa.c | 3 +-- module/zfs/spa_history.c | 5 ++--- module/zfs/vdev_indirect.c | 3 +-- module/zfs/vdev_initialize.c | 5 ++--- module/zfs/vdev_rebuild.c | 14 +++++--------- module/zfs/vdev_removal.c | 9 ++++----- module/zfs/vdev_trim.c | 5 ++--- 10 files changed, 26 insertions(+), 41 deletions(-) diff --git a/include/sys/dsl_synctask.h b/include/sys/dsl_synctask.h index 957963ffe5..0bb602e8f7 100644 --- a/include/sys/dsl_synctask.h +++ b/include/sys/dsl_synctask.h @@ -112,11 +112,11 @@ void dsl_sync_task_sync(dsl_sync_task_t *, dmu_tx_t *); int dsl_sync_task(const char *, dsl_checkfunc_t *, dsl_syncfunc_t *, void *, int, zfs_space_check_t); void dsl_sync_task_nowait(struct dsl_pool *, dsl_syncfunc_t *, - void *, int, zfs_space_check_t, dmu_tx_t *); + void *, dmu_tx_t *); int dsl_early_sync_task(const char *, dsl_checkfunc_t *, dsl_syncfunc_t *, void *, int, zfs_space_check_t); void dsl_early_sync_task_nowait(struct dsl_pool *, dsl_syncfunc_t *, - void *, int, zfs_space_check_t, dmu_tx_t *); + void *, dmu_tx_t *); int dsl_sync_task_sig(const char *, dsl_checkfunc_t *, dsl_syncfunc_t *, dsl_sigfunc_t *, void *, int, zfs_space_check_t); diff --git a/module/zfs/dmu_redact.c b/module/zfs/dmu_redact.c index df10d8d6fa..1c5f1bd248 100644 --- a/module/zfs/dmu_redact.c +++ b/module/zfs/dmu_redact.c @@ -568,8 +568,7 @@ commit_rl_updates(objset_t *os, struct merge_data *md, uint64_t object, uint64_t txg = dmu_tx_get_txg(tx); if (!md->md_synctask_txg[txg & TXG_MASK]) { dsl_sync_task_nowait(dmu_tx_pool(tx), - redaction_list_update_sync, md, 5, ZFS_SPACE_CHECK_NONE, - tx); + redaction_list_update_sync, md, tx); md->md_synctask_txg[txg & TXG_MASK] = B_TRUE; md->md_latest_synctask_txg = txg; } diff --git a/module/zfs/dsl_synctask.c b/module/zfs/dsl_synctask.c index 2d6ca8549e..148e8fff24 100644 --- a/module/zfs/dsl_synctask.c +++ b/module/zfs/dsl_synctask.c @@ -170,15 +170,13 @@ dsl_sync_task_sig(const char *pool, dsl_checkfunc_t *checkfunc, static void dsl_sync_task_nowait_common(dsl_pool_t *dp, dsl_syncfunc_t *syncfunc, void *arg, - int blocks_modified, zfs_space_check_t space_check, dmu_tx_t *tx, - boolean_t early) + dmu_tx_t *tx, boolean_t early) { dsl_sync_task_t *dst = kmem_zalloc(sizeof (*dst), KM_SLEEP); dst->dst_pool = dp; dst->dst_txg = dmu_tx_get_txg(tx); - dst->dst_space = blocks_modified << DST_AVG_BLKSHIFT; - dst->dst_space_check = space_check; + dst->dst_space_check = ZFS_SPACE_CHECK_NONE; dst->dst_checkfunc = dsl_null_checkfunc; dst->dst_syncfunc = syncfunc; dst->dst_arg = arg; @@ -192,18 +190,16 @@ dsl_sync_task_nowait_common(dsl_pool_t *dp, dsl_syncfunc_t *syncfunc, void *arg, void dsl_sync_task_nowait(dsl_pool_t *dp, dsl_syncfunc_t *syncfunc, void *arg, - int blocks_modified, zfs_space_check_t space_check, dmu_tx_t *tx) + dmu_tx_t *tx) { - dsl_sync_task_nowait_common(dp, syncfunc, arg, - blocks_modified, space_check, tx, B_FALSE); + dsl_sync_task_nowait_common(dp, syncfunc, arg, tx, B_FALSE); } void dsl_early_sync_task_nowait(dsl_pool_t *dp, dsl_syncfunc_t *syncfunc, void *arg, - int blocks_modified, zfs_space_check_t space_check, dmu_tx_t *tx) + dmu_tx_t *tx) { - dsl_sync_task_nowait_common(dp, syncfunc, arg, - blocks_modified, space_check, tx, B_TRUE); + dsl_sync_task_nowait_common(dp, syncfunc, arg, tx, B_TRUE); } /* diff --git a/module/zfs/spa.c b/module/zfs/spa.c index aac469f44b..31fa52d1d0 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -2688,8 +2688,7 @@ spa_livelist_condense_cb(void *arg, zthr_t *t) lca->first_size = first_size; lca->next_size = next_size; dsl_sync_task_nowait(spa_get_dsl(spa), - spa_livelist_condense_sync, lca, 0, - ZFS_SPACE_CHECK_NONE, tx); + spa_livelist_condense_sync, lca, tx); dmu_tx_commit(tx); return; } diff --git a/module/zfs/spa_history.c b/module/zfs/spa_history.c index f47adb94d5..2ab5881540 100644 --- a/module/zfs/spa_history.c +++ b/module/zfs/spa_history.c @@ -397,8 +397,7 @@ spa_history_log_nvl(spa_t *spa, nvlist_t *nvl) fnvlist_add_uint64(nvarg, ZPOOL_HIST_WHO, crgetruid(CRED())); /* Kick this off asynchronously; errors are ignored. */ - dsl_sync_task_nowait(spa_get_dsl(spa), spa_history_log_sync, - nvarg, 0, ZFS_SPACE_CHECK_NONE, tx); + dsl_sync_task_nowait(spa_get_dsl(spa), spa_history_log_sync, nvarg, tx); dmu_tx_commit(tx); /* spa_history_log_sync will free nvl */ @@ -532,7 +531,7 @@ log_internal(nvlist_t *nvl, const char *operation, spa_t *spa, spa_history_log_sync(nvl, tx); } else { dsl_sync_task_nowait(spa_get_dsl(spa), - spa_history_log_sync, nvl, 0, ZFS_SPACE_CHECK_NONE, tx); + spa_history_log_sync, nvl, tx); } /* spa_history_log_sync() will free nvl */ } diff --git a/module/zfs/vdev_indirect.c b/module/zfs/vdev_indirect.c index 6bc2d917d5..5301e0665a 100644 --- a/module/zfs/vdev_indirect.c +++ b/module/zfs/vdev_indirect.c @@ -576,8 +576,7 @@ spa_condense_indirect_commit_entry(spa_t *spa, */ if (list_is_empty(&sci->sci_new_mapping_entries[txgoff])) { dsl_sync_task_nowait(dmu_tx_pool(tx), - spa_condense_indirect_commit_sync, sci, - 0, ZFS_SPACE_CHECK_NONE, tx); + spa_condense_indirect_commit_sync, sci, tx); } vdev_indirect_mapping_entry_t *vime = diff --git a/module/zfs/vdev_initialize.c b/module/zfs/vdev_initialize.c index ab711441d9..7ff7fffcc8 100644 --- a/module/zfs/vdev_initialize.c +++ b/module/zfs/vdev_initialize.c @@ -126,7 +126,7 @@ vdev_initialize_change_state(vdev_t *vd, vdev_initializing_state_t new_state) dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir); VERIFY0(dmu_tx_assign(tx, TXG_WAIT)); dsl_sync_task_nowait(spa_get_dsl(spa), vdev_initialize_zap_update_sync, - guid, 2, ZFS_SPACE_CHECK_NONE, tx); + guid, tx); switch (new_state) { case VDEV_INITIALIZE_ACTIVE: @@ -216,8 +216,7 @@ vdev_initialize_write(vdev_t *vd, uint64_t start, uint64_t size, abd_t *data) /* This is the first write of this txg. */ dsl_sync_task_nowait(spa_get_dsl(spa), - vdev_initialize_zap_update_sync, guid, 2, - ZFS_SPACE_CHECK_RESERVED, tx); + vdev_initialize_zap_update_sync, guid, tx); } /* diff --git a/module/zfs/vdev_rebuild.c b/module/zfs/vdev_rebuild.c index 85ed8afe1c..3362d608c0 100644 --- a/module/zfs/vdev_rebuild.c +++ b/module/zfs/vdev_rebuild.c @@ -267,7 +267,7 @@ vdev_rebuild_initiate(vdev_t *vd) vd->vdev_rebuilding = B_TRUE; dsl_sync_task_nowait(spa_get_dsl(spa), vdev_rebuild_initiate_sync, - (void *)(uintptr_t)vd->vdev_id, 0, ZFS_SPACE_CHECK_NONE, tx); + (void *)(uintptr_t)vd->vdev_id, tx); dmu_tx_commit(tx); vdev_rebuild_log_notify(spa, vd, ESC_ZFS_RESILVER_START); @@ -553,8 +553,7 @@ vdev_rebuild_range(vdev_rebuild_t *vr, uint64_t start, uint64_t size) vr->vr_scan_offset[txg & TXG_MASK] = start; dsl_sync_task_nowait(spa_get_dsl(spa), vdev_rebuild_update_sync, - (void *)(uintptr_t)vd->vdev_id, 2, - ZFS_SPACE_CHECK_RESERVED, tx); + (void *)(uintptr_t)vd->vdev_id, tx); } /* When exiting write out our progress. */ @@ -875,16 +874,14 @@ vdev_rebuild_thread(void *arg) * by a pool checkpoint. See the dsl_scan_done() comments. */ dsl_sync_task_nowait(dp, vdev_rebuild_complete_sync, - (void *)(uintptr_t)vd->vdev_id, 0, - ZFS_SPACE_CHECK_NONE, tx); + (void *)(uintptr_t)vd->vdev_id, tx); } else if (vd->vdev_rebuild_cancel_wanted) { /* * The rebuild operation was canceled. This will occur when * a device participating in the rebuild is detached. */ dsl_sync_task_nowait(dp, vdev_rebuild_cancel_sync, - (void *)(uintptr_t)vd->vdev_id, 0, - ZFS_SPACE_CHECK_NONE, tx); + (void *)(uintptr_t)vd->vdev_id, tx); } else if (vd->vdev_rebuild_reset_wanted) { /* * Reset the running rebuild without canceling and restarting @@ -892,8 +889,7 @@ vdev_rebuild_thread(void *arg) * participate in the rebuild. */ dsl_sync_task_nowait(dp, vdev_rebuild_reset_sync, - (void *)(uintptr_t)vd->vdev_id, 0, - ZFS_SPACE_CHECK_NONE, tx); + (void *)(uintptr_t)vd->vdev_id, tx); } else { /* * The rebuild operation should be suspended. This may occur diff --git a/module/zfs/vdev_removal.c b/module/zfs/vdev_removal.c index 56e420871f..fdeca7ab34 100644 --- a/module/zfs/vdev_removal.c +++ b/module/zfs/vdev_removal.c @@ -1167,8 +1167,8 @@ vdev_remove_replace_with_indirect(vdev_t *vd, uint64_t txg) /* After this, we can not use svr. */ tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg); - dsl_sync_task_nowait(spa->spa_dsl_pool, vdev_remove_complete_sync, svr, - 0, ZFS_SPACE_CHECK_NONE, tx); + dsl_sync_task_nowait(spa->spa_dsl_pool, + vdev_remove_complete_sync, svr, tx); dmu_tx_commit(tx); } @@ -1317,7 +1317,7 @@ spa_vdev_copy_impl(vdev_t *vd, spa_vdev_removal_t *svr, vdev_copy_arg_t *vca, if (svr->svr_max_offset_to_sync[txg & TXG_MASK] == 0) { dsl_sync_task_nowait(dmu_tx_pool(tx), vdev_mapping_sync, - svr, 0, ZFS_SPACE_CHECK_NONE, tx); + svr, tx); } svr->svr_max_offset_to_sync[txg & TXG_MASK] = range_tree_max(segs); @@ -2143,8 +2143,7 @@ spa_vdev_remove_top(vdev_t *vd, uint64_t *txg) vdev_config_dirty(vd); dmu_tx_t *tx = dmu_tx_create_assigned(spa->spa_dsl_pool, *txg); dsl_sync_task_nowait(spa->spa_dsl_pool, - vdev_remove_initiate_sync, - (void *)(uintptr_t)vd->vdev_id, 0, ZFS_SPACE_CHECK_NONE, tx); + vdev_remove_initiate_sync, (void *)(uintptr_t)vd->vdev_id, tx); dmu_tx_commit(tx); return (0); diff --git a/module/zfs/vdev_trim.c b/module/zfs/vdev_trim.c index 7383e14933..02b42ddd5a 100644 --- a/module/zfs/vdev_trim.c +++ b/module/zfs/vdev_trim.c @@ -317,7 +317,7 @@ vdev_trim_change_state(vdev_t *vd, vdev_trim_state_t new_state, dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir); VERIFY0(dmu_tx_assign(tx, TXG_WAIT)); dsl_sync_task_nowait(spa_get_dsl(spa), vdev_trim_zap_update_sync, - guid, 2, ZFS_SPACE_CHECK_NONE, tx); + guid, tx); switch (new_state) { case VDEV_TRIM_ACTIVE: @@ -510,8 +510,7 @@ vdev_trim_range(trim_args_t *ta, uint64_t start, uint64_t size) /* This is the first write of this txg. */ dsl_sync_task_nowait(spa_get_dsl(spa), - vdev_trim_zap_update_sync, guid, 2, - ZFS_SPACE_CHECK_RESERVED, tx); + vdev_trim_zap_update_sync, guid, tx); } /*