Skip to content

Commit 815ac54

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 c98295e commit 815ac54

File tree

4 files changed

+53
-15
lines changed

4 files changed

+53
-15
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
@@ -817,6 +817,8 @@ extern void spa_l2cache_drop(spa_t *spa);
817817

818818
/* scanning */
819819
extern int spa_scan(spa_t *spa, pool_scan_func_t func);
820+
extern int spa_scan_range(spa_t *spa, pool_scan_func_t func, uint64_t txgstart,
821+
uint64_t txgend);
820822
extern int spa_scan_stop(spa_t *spa);
821823
extern int spa_scrub_pause_resume(spa_t *spa, pool_scrub_cmd_t flag);
822824

module/zfs/dsl_scan.c

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -846,18 +846,24 @@ dsl_scan_setup_check(void *arg, dmu_tx_t *tx)
846846
return (0);
847847
}
848848

849+
typedef struct {
850+
pool_scan_func_t func;
851+
uint64_t txgstart;
852+
uint64_t txgend;
853+
} setup_sync_arg_t;
854+
849855
void
850856
dsl_scan_setup_sync(void *arg, dmu_tx_t *tx)
851857
{
852-
(void) arg;
858+
setup_sync_arg_t *setup_sync_arg = (setup_sync_arg_t *)arg;
853859
dsl_scan_t *scn = dmu_tx_pool(tx)->dp_scan;
854-
pool_scan_func_t *funcp = arg;
855860
dmu_object_type_t ot = 0;
856861
dsl_pool_t *dp = scn->scn_dp;
857862
spa_t *spa = dp->dp_spa;
858863

859864
ASSERT(!dsl_scan_is_running(scn));
860-
ASSERT(*funcp > POOL_SCAN_NONE && *funcp < POOL_SCAN_FUNCS);
865+
ASSERT(setup_sync_arg->func > POOL_SCAN_NONE &&
866+
setup_sync_arg->func < POOL_SCAN_FUNCS);
861867
memset(&scn->scn_phys, 0, sizeof (scn->scn_phys));
862868

863869
/*
@@ -867,10 +873,14 @@ dsl_scan_setup_sync(void *arg, dmu_tx_t *tx)
867873
memset(&scn->errorscrub_phys, 0, sizeof (scn->errorscrub_phys));
868874
dsl_errorscrub_sync_state(scn, tx);
869875

870-
scn->scn_phys.scn_func = *funcp;
876+
scn->scn_phys.scn_func = setup_sync_arg->func;
871877
scn->scn_phys.scn_state = DSS_SCANNING;
872-
scn->scn_phys.scn_min_txg = 0;
873-
scn->scn_phys.scn_max_txg = tx->tx_txg;
878+
scn->scn_phys.scn_min_txg = setup_sync_arg->txgstart;
879+
if (setup_sync_arg->txgend == 0) {
880+
scn->scn_phys.scn_max_txg = tx->tx_txg;
881+
} else {
882+
scn->scn_phys.scn_max_txg = setup_sync_arg->txgend;
883+
}
874884
scn->scn_phys.scn_ddt_class_max = DDT_CLASSES - 1; /* the entire DDT */
875885
scn->scn_phys.scn_start_time = gethrestime_sec();
876886
scn->scn_phys.scn_errors = 0;
@@ -955,7 +965,7 @@ dsl_scan_setup_sync(void *arg, dmu_tx_t *tx)
955965

956966
spa_history_log_internal(spa, "scan setup", tx,
957967
"func=%u mintxg=%llu maxtxg=%llu",
958-
*funcp, (u_longlong_t)scn->scn_phys.scn_min_txg,
968+
setup_sync_arg->func, (u_longlong_t)scn->scn_phys.scn_min_txg,
959969
(u_longlong_t)scn->scn_phys.scn_max_txg);
960970
}
961971

@@ -965,10 +975,16 @@ dsl_scan_setup_sync(void *arg, dmu_tx_t *tx)
965975
* error scrub.
966976
*/
967977
int
968-
dsl_scan(dsl_pool_t *dp, pool_scan_func_t func)
978+
dsl_scan(dsl_pool_t *dp, pool_scan_func_t func, uint64_t txgstart,
979+
uint64_t txgend)
969980
{
970981
spa_t *spa = dp->dp_spa;
971982
dsl_scan_t *scn = dp->dp_scan;
983+
setup_sync_arg_t setup_sync_arg;
984+
985+
if (func != POOL_SCAN_SCRUB && (txgstart != 0 || txgend != 0)) {
986+
return (EINVAL);
987+
}
972988

973989
/*
974990
* Purge all vdev caches and probe all devices. We do this here
@@ -1019,8 +1035,13 @@ dsl_scan(dsl_pool_t *dp, pool_scan_func_t func)
10191035
return (SET_ERROR(err));
10201036
}
10211037

1038+
setup_sync_arg.func = func;
1039+
setup_sync_arg.txgstart = txgstart;
1040+
setup_sync_arg.txgend = txgend;
1041+
10221042
return (dsl_sync_task(spa_name(spa), dsl_scan_setup_check,
1023-
dsl_scan_setup_sync, &func, 0, ZFS_SPACE_CHECK_EXTRA_RESERVED));
1043+
dsl_scan_setup_sync, &setup_sync_arg, 0,
1044+
ZFS_SPACE_CHECK_EXTRA_RESERVED));
10241045
}
10251046

10261047
static void
@@ -4283,13 +4304,16 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx)
42834304
*/
42844305
if (dsl_scan_restarting(scn, tx) ||
42854306
(spa->spa_resilver_deferred && zfs_resilver_disable_defer)) {
4286-
pool_scan_func_t func = POOL_SCAN_SCRUB;
4307+
setup_sync_arg_t setup_sync_arg = {
4308+
.func = POOL_SCAN_SCRUB,
4309+
};
42874310
dsl_scan_done(scn, B_FALSE, tx);
42884311
if (vdev_resilver_needed(spa->spa_root_vdev, NULL, NULL))
4289-
func = POOL_SCAN_RESILVER;
4312+
setup_sync_arg.func = POOL_SCAN_RESILVER;
42904313
zfs_dbgmsg("restarting scan func=%u on %s txg=%llu",
4291-
func, dp->dp_spa->spa_name, (longlong_t)tx->tx_txg);
4292-
dsl_scan_setup_sync(&func, tx);
4314+
setup_sync_arg.func, dp->dp_spa->spa_name,
4315+
(longlong_t)tx->tx_txg);
4316+
dsl_scan_setup_sync(&setup_sync_arg, tx);
42934317
}
42944318

42954319
/*

module/zfs/spa.c

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

87938793
int
87948794
spa_scan(spa_t *spa, pool_scan_func_t func)
8795+
{
8796+
return (spa_scan_range(spa, func, 0, 0));
8797+
}
8798+
8799+
int
8800+
spa_scan_range(spa_t *spa, pool_scan_func_t func, uint64_t txgstart,
8801+
uint64_t txgend)
87958802
{
87968803
ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == 0);
87978804

@@ -8802,6 +8809,9 @@ spa_scan(spa_t *spa, pool_scan_func_t func)
88028809
!spa_feature_is_enabled(spa, SPA_FEATURE_RESILVER_DEFER))
88038810
return (SET_ERROR(ENOTSUP));
88048811

8812+
if (func != POOL_SCAN_SCRUB && (txgstart != 0 || txgend != 0))
8813+
return (SET_ERROR(ENOTSUP));
8814+
88058815
/*
88068816
* If a resilver was requested, but there is no DTL on a
88078817
* writeable leaf device, we have nothing to do.
@@ -8816,7 +8826,7 @@ spa_scan(spa_t *spa, pool_scan_func_t func)
88168826
!spa_feature_is_enabled(spa, SPA_FEATURE_HEAD_ERRLOG))
88178827
return (SET_ERROR(ENOTSUP));
88188828

8819-
return (dsl_scan(spa->spa_dsl_pool, func));
8829+
return (dsl_scan(spa->spa_dsl_pool, func, txgstart, txgend));
88208830
}
88218831

88228832
/*
@@ -10894,6 +10904,7 @@ EXPORT_SYMBOL(spa_l2cache_drop);
1089410904

1089510905
/* scanning */
1089610906
EXPORT_SYMBOL(spa_scan);
10907+
EXPORT_SYMBOL(spa_scan_range);
1089710908
EXPORT_SYMBOL(spa_scan_stop);
1089810909

1089910910
/* spa syncing */

0 commit comments

Comments
 (0)