summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorAlexander Motin <[email protected]>2020-03-12 13:52:03 -0400
committerGitHub <[email protected]>2020-03-12 10:52:03 -0700
commitfa130e010c2ff9b33aba11d2699b667e454b3ccb (patch)
tree314b2e6594df1cabc5ef0aa94fdc41ed5cead2e4 /module/zfs
parent94eb65b4c1ff02653c00c8f30b1a2a9617afa556 (diff)
Fix infinite scan on a pool with only special allocations
Attempt to run scrub or resilver on a new pool containing only special allocations (special vdev added on creation) caused infinite loop because of dsl_scan_should_clear() limiting memory usage to 5% of pool size, which it calculated accounting only normal allocation class. Addition of special and just in case dedup classes fixes the issue. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Alexander Motin <[email protected]> Sponsored-By: iXsystems, Inc. Closes #10106 Closes #8694
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/dsl_scan.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/module/zfs/dsl_scan.c b/module/zfs/dsl_scan.c
index d615e133b..74ef2e155 100644
--- a/module/zfs/dsl_scan.c
+++ b/module/zfs/dsl_scan.c
@@ -1194,10 +1194,13 @@ scan_ds_queue_sync(dsl_scan_t *scn, dmu_tx_t *tx)
static boolean_t
dsl_scan_should_clear(dsl_scan_t *scn)
{
+ spa_t *spa = scn->scn_dp->dp_spa;
vdev_t *rvd = scn->scn_dp->dp_spa->spa_root_vdev;
- uint64_t mlim_hard, mlim_soft, mused;
- uint64_t alloc = metaslab_class_get_alloc(spa_normal_class(
- scn->scn_dp->dp_spa));
+ uint64_t alloc, mlim_hard, mlim_soft, mused;
+
+ alloc = metaslab_class_get_alloc(spa_normal_class(spa));
+ alloc += metaslab_class_get_alloc(spa_special_class(spa));
+ alloc += metaslab_class_get_alloc(spa_dedup_class(spa));
mlim_hard = MAX((physmem / zfs_scan_mem_lim_fact) * PAGESIZE,
zfs_scan_mem_lim_min);