Skip to content

Commit f2aca4b

Browse files
committed
Redesign scan/scrub interfact to allow scrubing range of TXGs
Sponsored-By: Wasabi Technology, Inc. Sponsored-By: Klara Inc. Signed-off-by: Mariusz Zaborski <[email protected]>
1 parent 46c4f2c commit f2aca4b

File tree

4 files changed

+53
-16
lines changed

4 files changed

+53
-16
lines changed

include/sys/dsl_scan.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ void dsl_scan_setup_sync(void *, dmu_tx_t *);
189189
void dsl_scan_fini(struct dsl_pool *dp);
190190
void dsl_scan_sync(struct dsl_pool *, dmu_tx_t *);
191191
int dsl_scan_cancel(struct dsl_pool *);
192-
int dsl_scan(struct dsl_pool *, pool_scan_func_t);
192+
int dsl_scan(struct dsl_pool *, pool_scan_func_t, uint64_t starttxg,
193+
uint64_t txgend);
193194
void dsl_scan_assess_vdev(struct dsl_pool *dp, vdev_t *vd);
194195
boolean_t dsl_scan_scrubbing(const struct dsl_pool *dp);
195196
boolean_t dsl_errorscrubbing(const struct dsl_pool *dp);

include/sys/spa.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,8 @@ extern void spa_l2cache_drop(spa_t *spa);
821821

822822
/* scanning */
823823
extern int spa_scan(spa_t *spa, pool_scan_func_t func);
824+
extern int spa_scan_range(spa_t *spa, pool_scan_func_t func, uint64_t txgstart,
825+
uint64_t txgend);
824826
extern int spa_scan_stop(spa_t *spa);
825827
extern int spa_scrub_pause_resume(spa_t *spa, pool_scrub_cmd_t flag);
826828

module/zfs/dsl_scan.c

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -852,18 +852,24 @@ dsl_scan_setup_check(void *arg, dmu_tx_t *tx)
852852
return (0);
853853
}
854854

855+
typedef struct {
856+
pool_scan_func_t func;
857+
uint64_t txgstart;
858+
uint64_t txgend;
859+
} setup_sync_arg_t;
860+
855861
void
856862
dsl_scan_setup_sync(void *arg, dmu_tx_t *tx)
857863
{
858-
(void) arg;
864+
setup_sync_arg_t *setup_sync_arg = (setup_sync_arg_t *)arg;
859865
dsl_scan_t *scn = dmu_tx_pool(tx)->dp_scan;
860-
pool_scan_func_t *funcp = arg;
861866
dmu_object_type_t ot = 0;
862867
dsl_pool_t *dp = scn->scn_dp;
863868
spa_t *spa = dp->dp_spa;
864869

865870
ASSERT(!dsl_scan_is_running(scn));
866-
ASSERT(*funcp > POOL_SCAN_NONE && *funcp < POOL_SCAN_FUNCS);
871+
ASSERT3U(setup_sync_arg->func, >, POOL_SCAN_NONE);
872+
ASSERT3U(setup_sync_arg->func, <, POOL_SCAN_FUNCS);
867873
memset(&scn->scn_phys, 0, sizeof (scn->scn_phys));
868874

869875
/*
@@ -873,10 +879,14 @@ dsl_scan_setup_sync(void *arg, dmu_tx_t *tx)
873879
memset(&scn->errorscrub_phys, 0, sizeof (scn->errorscrub_phys));
874880
dsl_errorscrub_sync_state(scn, tx);
875881

876-
scn->scn_phys.scn_func = *funcp;
882+
scn->scn_phys.scn_func = setup_sync_arg->func;
877883
scn->scn_phys.scn_state = DSS_SCANNING;
878-
scn->scn_phys.scn_min_txg = 0;
879-
scn->scn_phys.scn_max_txg = tx->tx_txg;
884+
scn->scn_phys.scn_min_txg = setup_sync_arg->txgstart;
885+
if (setup_sync_arg->txgend == 0) {
886+
scn->scn_phys.scn_max_txg = tx->tx_txg;
887+
} else {
888+
scn->scn_phys.scn_max_txg = setup_sync_arg->txgend;
889+
}
880890
scn->scn_phys.scn_ddt_class_max = DDT_CLASSES - 1; /* the entire DDT */
881891
scn->scn_phys.scn_start_time = gethrestime_sec();
882892
scn->scn_phys.scn_errors = 0;
@@ -963,7 +973,7 @@ dsl_scan_setup_sync(void *arg, dmu_tx_t *tx)
963973

964974
spa_history_log_internal(spa, "scan setup", tx,
965975
"func=%u mintxg=%llu maxtxg=%llu",
966-
*funcp, (u_longlong_t)scn->scn_phys.scn_min_txg,
976+
setup_sync_arg->func, (u_longlong_t)scn->scn_phys.scn_min_txg,
967977
(u_longlong_t)scn->scn_phys.scn_max_txg);
968978
}
969979

@@ -973,10 +983,16 @@ dsl_scan_setup_sync(void *arg, dmu_tx_t *tx)
973983
* error scrub.
974984
*/
975985
int
976-
dsl_scan(dsl_pool_t *dp, pool_scan_func_t func)
986+
dsl_scan(dsl_pool_t *dp, pool_scan_func_t func, uint64_t txgstart,
987+
uint64_t txgend)
977988
{
978989
spa_t *spa = dp->dp_spa;
979990
dsl_scan_t *scn = dp->dp_scan;
991+
setup_sync_arg_t setup_sync_arg;
992+
993+
if (func != POOL_SCAN_SCRUB && (txgstart != 0 || txgend != 0)) {
994+
return (EINVAL);
995+
}
980996

981997
/*
982998
* Purge all vdev caches and probe all devices. We do this here
@@ -1027,8 +1043,13 @@ dsl_scan(dsl_pool_t *dp, pool_scan_func_t func)
10271043
return (SET_ERROR(err));
10281044
}
10291045

1046+
setup_sync_arg.func = func;
1047+
setup_sync_arg.txgstart = txgstart;
1048+
setup_sync_arg.txgend = txgend;
1049+
10301050
return (dsl_sync_task(spa_name(spa), dsl_scan_setup_check,
1031-
dsl_scan_setup_sync, &func, 0, ZFS_SPACE_CHECK_EXTRA_RESERVED));
1051+
dsl_scan_setup_sync, &setup_sync_arg, 0,
1052+
ZFS_SPACE_CHECK_EXTRA_RESERVED));
10321053
}
10331054

10341055
static void
@@ -4330,14 +4351,16 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx)
43304351
* current scan progress is below zfs_resilver_defer_percent.
43314352
*/
43324353
if (dsl_scan_restarting(scn, tx) || restart_early) {
4333-
pool_scan_func_t func = POOL_SCAN_SCRUB;
4354+
setup_sync_arg_t setup_sync_arg = {
4355+
.func = POOL_SCAN_SCRUB,
4356+
};
43344357
dsl_scan_done(scn, B_FALSE, tx);
43354358
if (vdev_resilver_needed(spa->spa_root_vdev, NULL, NULL))
4336-
func = POOL_SCAN_RESILVER;
4359+
setup_sync_arg.func = POOL_SCAN_RESILVER;
43374360
zfs_dbgmsg("restarting scan func=%u on %s txg=%llu early=%d",
4338-
func, dp->dp_spa->spa_name, (longlong_t)tx->tx_txg,
4339-
restart_early);
4340-
dsl_scan_setup_sync(&func, tx);
4361+
setup_sync_arg.func, dp->dp_spa->spa_name,
4362+
(longlong_t)tx->tx_txg, restart_early);
4363+
dsl_scan_setup_sync(&setup_sync_arg, tx);
43414364
}
43424365

43434366
/*

module/zfs/spa.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8867,6 +8867,13 @@ spa_scan_stop(spa_t *spa)
88678867

88688868
int
88698869
spa_scan(spa_t *spa, pool_scan_func_t func)
8870+
{
8871+
return (spa_scan_range(spa, func, 0, 0));
8872+
}
8873+
8874+
int
8875+
spa_scan_range(spa_t *spa, pool_scan_func_t func, uint64_t txgstart,
8876+
uint64_t txgend)
88708877
{
88718878
ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == 0);
88728879

@@ -8877,6 +8884,9 @@ spa_scan(spa_t *spa, pool_scan_func_t func)
88778884
!spa_feature_is_enabled(spa, SPA_FEATURE_RESILVER_DEFER))
88788885
return (SET_ERROR(ENOTSUP));
88798886

8887+
if (func != POOL_SCAN_SCRUB && (txgstart != 0 || txgend != 0))
8888+
return (SET_ERROR(ENOTSUP));
8889+
88808890
/*
88818891
* If a resilver was requested, but there is no DTL on a
88828892
* writeable leaf device, we have nothing to do.
@@ -8891,7 +8901,7 @@ spa_scan(spa_t *spa, pool_scan_func_t func)
88918901
!spa_feature_is_enabled(spa, SPA_FEATURE_HEAD_ERRLOG))
88928902
return (SET_ERROR(ENOTSUP));
88938903

8894-
return (dsl_scan(spa->spa_dsl_pool, func));
8904+
return (dsl_scan(spa->spa_dsl_pool, func, txgstart, txgend));
88958905
}
88968906

88978907
/*
@@ -10974,6 +10984,7 @@ EXPORT_SYMBOL(spa_l2cache_drop);
1097410984

1097510985
/* scanning */
1097610986
EXPORT_SYMBOL(spa_scan);
10987+
EXPORT_SYMBOL(spa_scan_range);
1097710988
EXPORT_SYMBOL(spa_scan_stop);
1097810989

1097910990
/* spa syncing */

0 commit comments

Comments
 (0)