aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/dsl_scan.c
diff options
context:
space:
mode:
authorTom Caputi <[email protected]>2018-12-06 12:47:23 -0500
committerBrian Behlendorf <[email protected]>2018-12-06 09:47:23 -0800
commitd6496040d904c381d7ecdb113cfcab4964e033c1 (patch)
treedf6fde310a69cd7cc51837f6b095073b141d3b75 /module/zfs/dsl_scan.c
parentb53cb02d925258ada06282d7dc4223a251edb5cb (diff)
Ensure dsl scan prefetch queue is emptied
This patch simply ensures that scn->scn_prefetch_queue is emptied before the kernel module is unloaded and when scanning completes. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Alek Pinchuk <[email protected]> Signed-off-by: Tom Caputi <[email protected]> Closes #8178
Diffstat (limited to 'module/zfs/dsl_scan.c')
-rw-r--r--module/zfs/dsl_scan.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/module/zfs/dsl_scan.c b/module/zfs/dsl_scan.c
index d9d9900a2..3180ce65a 100644
--- a/module/zfs/dsl_scan.c
+++ b/module/zfs/dsl_scan.c
@@ -119,6 +119,7 @@ static scan_cb_t dsl_scan_scrub_cb;
static int scan_ds_queue_compare(const void *a, const void *b);
static int scan_prefetch_queue_compare(const void *a, const void *b);
static void scan_ds_queue_clear(dsl_scan_t *scn);
+static void scan_ds_prefetch_queue_clear(dsl_scan_t *scn);
static boolean_t scan_ds_queue_contains(dsl_scan_t *scn, uint64_t dsobj,
uint64_t *txg);
static void scan_ds_queue_insert(dsl_scan_t *scn, uint64_t dsobj, uint64_t txg);
@@ -514,8 +515,10 @@ dsl_scan_fini(dsl_pool_t *dp)
if (scn->scn_taskq != NULL)
taskq_destroy(scn->scn_taskq);
+
scan_ds_queue_clear(scn);
avl_destroy(&scn->scn_queue);
+ scan_ds_prefetch_queue_clear(scn);
avl_destroy(&scn->scn_prefetch_queue);
kmem_free(dp->dp_scan, sizeof (dsl_scan_t));
@@ -812,6 +815,7 @@ dsl_scan_done(dsl_scan_t *scn, boolean_t complete, dmu_tx_t *tx)
scn->scn_phys.scn_queue_obj = 0;
}
scan_ds_queue_clear(scn);
+ scan_ds_prefetch_queue_clear(scn);
scn->scn_phys.scn_flags &= ~DSF_SCRUB_PAUSED;
@@ -1413,6 +1417,22 @@ scan_prefetch_ctx_add_ref(scan_prefetch_ctx_t *spc, void *tag)
zfs_refcount_add(&spc->spc_refcnt, tag);
}
+static void
+scan_ds_prefetch_queue_clear(dsl_scan_t *scn)
+{
+ spa_t *spa = scn->scn_dp->dp_spa;
+ void *cookie = NULL;
+ scan_prefetch_issue_ctx_t *spic = NULL;
+
+ mutex_enter(&spa->spa_scrub_lock);
+ while ((spic = avl_destroy_nodes(&scn->scn_prefetch_queue,
+ &cookie)) != NULL) {
+ scan_prefetch_ctx_rele(spic->spic_spc, scn);
+ kmem_free(spic, sizeof (scan_prefetch_issue_ctx_t));
+ }
+ mutex_exit(&spa->spa_scrub_lock);
+}
+
static boolean_t
dsl_scan_check_prefetch_resume(scan_prefetch_ctx_t *spc,
const zbookmark_phys_t *zb)