aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Caputi <tcaputi@datto.com>2018-10-18 08:13:07 +0000
committerBrian Behlendorf <behlendorf1@llnl.gov>2018-10-24 21:37:15 +0000
commit5e0bd0ae056e26de36dee3c199c6fcff8f14ee15 (patch)
tree1e6e7487e71c0db8ca50b1ef73f3654ab3a974d6
parenta783dd96843699744e0543b579b5f50c9023432f (diff)
downloadsrc-5e0bd0ae056e26de36dee3c199c6fcff8f14ee15.tar.gz
src-5e0bd0ae056e26de36dee3c199c6fcff8f14ee15.zip
Fix issue with scanning dedup blocks as scan ends
This patch fixes an issue discovered by ztest where dsl_scan_ddt_entry() could add I/Os to the dsl scan queues between when the scan had finished all required work and when the scan was marked as complete. This caused the scan to spin indefinitely without ending. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Serapheim Dimitropoulos <serapheim.dimitro@delphix.com> Reviewed-by: Matthew Ahrens <mahrens@delphix.com> Signed-off-by: Tom Caputi <tcaputi@datto.com> Closes #8010
-rw-r--r--module/zfs/dsl_scan.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/module/zfs/dsl_scan.c b/module/zfs/dsl_scan.c
index aff99f275efd..db3295363813 100644
--- a/module/zfs/dsl_scan.c
+++ b/module/zfs/dsl_scan.c
@@ -2386,6 +2386,20 @@ dsl_scan_ddt_entry(dsl_scan_t *scn, enum zio_checksum checksum,
if (!dsl_scan_is_running(scn))
return;
+ /*
+ * This function is special because it is the only thing
+ * that can add scan_io_t's to the vdev scan queues from
+ * outside dsl_scan_sync(). For the most part this is ok
+ * as long as it is called from within syncing context.
+ * However, dsl_scan_sync() expects that no new sio's will
+ * be added between when all the work for a scan is done
+ * and the next txg when the scan is actually marked as
+ * completed. This check ensures we do not issue new sio's
+ * during this period.
+ */
+ if (scn->scn_done_txg != 0)
+ return;
+
for (p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
if (ddp->ddp_phys_birth == 0 ||
ddp->ddp_phys_birth > scn->scn_phys.scn_max_txg)
@@ -3468,6 +3482,8 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx)
(longlong_t)tx->tx_txg);
}
} else if (scn->scn_is_sorted && scn->scn_bytes_pending != 0) {
+ ASSERT(scn->scn_clearing);
+
/* need to issue scrubbing IOs from per-vdev queues */
scn->scn_zio_root = zio_root(dp->dp_spa, NULL,
NULL, ZIO_FLAG_CANFAIL);