Skip to content

Commit 4823cc2

Browse files
committed
scrub: add option to scrub only recent data
Sponsored-By: Wasabi Technology, Inc. Sponsored-By: Klara Inc. Signed-off-by: Mariusz Zaborski <[email protected]>
1 parent 4dde5c3 commit 4823cc2

File tree

8 files changed

+86
-17
lines changed

8 files changed

+86
-17
lines changed

cmd/zpool/zpool_main.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ get_usage(zpool_help_t idx)
506506
return (gettext("\tinitialize [-c | -s | -u] [-w] <pool> "
507507
"[<device> ...]\n"));
508508
case HELP_SCRUB:
509-
return (gettext("\tscrub [-s | -p] [-w] [-e] [-C] "
509+
return (gettext("\tscrub [-s | -p] [-w] [-e] [-C] [-R] "
510510
"<pool> ...\n"));
511511
case HELP_RESILVER:
512512
return (gettext("\tresilver <pool> ...\n"));
@@ -8398,6 +8398,7 @@ wait_callback(zpool_handle_t *zhp, void *data)
83988398
* -e Only scrub blocks in the error log.
83998399
* -s Stop. Stops any in-progress scrub.
84008400
* -p Pause. Pause in-progress scrub.
8401+
* -R Scrub only recent data.
84018402
* -w Wait. Blocks until scrub has completed.
84028403
*/
84038404
int
@@ -8415,9 +8416,10 @@ zpool_do_scrub(int argc, char **argv)
84158416
boolean_t is_pause = B_FALSE;
84168417
boolean_t is_stop = B_FALSE;
84178418
boolean_t is_txg_continue = B_FALSE;
8419+
boolean_t is_recent_scrub = B_FALSE;
84188420

84198421
/* check options */
8420-
while ((c = getopt(argc, argv, "spweC")) != -1) {
8422+
while ((c = getopt(argc, argv, "spweCR")) != -1) {
84218423
switch (c) {
84228424
case 'C':
84238425
is_txg_continue = B_TRUE;
@@ -8431,6 +8433,9 @@ zpool_do_scrub(int argc, char **argv)
84318433
case 'p':
84328434
is_pause = B_TRUE;
84338435
break;
8436+
case 'R':
8437+
is_recent_scrub = B_TRUE;
8438+
break;
84348439
case 'w':
84358440
wait = B_TRUE;
84368441
break;
@@ -8457,11 +8462,26 @@ zpool_do_scrub(int argc, char **argv)
84578462
(void) fprintf(stderr, gettext("invalid option "
84588463
"combination :-e and -C are mutually exclusive\n"));
84598464
usage(B_FALSE);
8465+
} else if (is_pause && is_recent_scrub) {
8466+
(void) fprintf(stderr, gettext("invalid option "
8467+
"combination :-p and -R are mutually exclusive\n"));
8468+
usage(B_FALSE);
8469+
} else if (is_stop && is_recent_scrub) {
8470+
(void) fprintf(stderr, gettext("invalid option "
8471+
"combination :-s and -R are mutually exclusive\n"));
8472+
usage(B_FALSE);
8473+
} else if (is_error_scrub && is_recent_scrub) {
8474+
(void) fprintf(stderr, gettext("invalid option "
8475+
"combination :-e and -R are mutually exclusive\n"));
8476+
usage(B_FALSE);
84608477
} else {
8461-
if (is_error_scrub)
8478+
if (is_error_scrub) {
84628479
cb.cb_type = POOL_SCAN_ERRORSCRUB;
8480+
}
84638481

8464-
if (is_pause) {
8482+
if (is_recent_scrub) {
8483+
cb.cb_scrub_cmd = POOL_SCRUB_RECENT_TXGS;
8484+
} else if (is_pause) {
84658485
cb.cb_scrub_cmd = POOL_SCRUB_PAUSE;
84668486
} else if (is_stop) {
84678487
cb.cb_type = POOL_SCAN_NONE;

include/sys/dsl_scan.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct dsl_pool;
4444
struct dmu_tx;
4545

4646
extern int zfs_scan_suspend_progress;
47+
extern uint_t zfs_scrub_recent_txgs;
4748

4849
/*
4950
* All members of this structure must be uint64_t, for byteswap

include/sys/fs/zfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,7 @@ typedef enum pool_scrub_cmd {
10771077
POOL_SCRUB_NORMAL = 0,
10781078
POOL_SCRUB_PAUSE,
10791079
POOL_SCRUB_FROM_LAST_TXG,
1080+
POOL_SCRUB_RECENT_TXGS,
10801081
POOL_SCRUB_FLAGS_END
10811082
} pool_scrub_cmd_t;
10821083

lib/libzfs/libzfs.abi

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@
183183
<elf-symbol name='fsleep' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
184184
<elf-symbol name='get_dataset_depth' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
185185
<elf-symbol name='get_system_hostid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
186-
<elf-symbol name='getexecname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
187186
<elf-symbol name='get_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
187+
<elf-symbol name='getexecname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
188188
<elf-symbol name='getextmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
189189
<elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
190190
<elf-symbol name='getprop_uint64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -466,6 +466,7 @@
466466
<elf-symbol name='zpool_clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
467467
<elf-symbol name='zpool_clear_label' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
468468
<elf-symbol name='zpool_close' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
469+
<elf-symbol name='zpool_collect_unsup_feat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
469470
<elf-symbol name='zpool_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
470471
<elf-symbol name='zpool_default_search_paths' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
471472
<elf-symbol name='zpool_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -485,8 +486,8 @@
485486
<elf-symbol name='zpool_export_force' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
486487
<elf-symbol name='zpool_feature_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
487488
<elf-symbol name='zpool_find_config' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
488-
<elf-symbol name='zpool_find_vdev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
489489
<elf-symbol name='zpool_find_parent_vdev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
490+
<elf-symbol name='zpool_find_vdev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
490491
<elf-symbol name='zpool_find_vdev_by_physpath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
491492
<elf-symbol name='zpool_free_handles' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
492493
<elf-symbol name='zpool_get_all_vdev_props' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -529,7 +530,6 @@
529530
<elf-symbol name='zpool_prefetch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
530531
<elf-symbol name='zpool_prepare_and_label_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
531532
<elf-symbol name='zpool_prepare_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
532-
<elf-symbol name='zpool_collect_unsup_feat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
533533
<elf-symbol name='zpool_prop_align_right' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
534534
<elf-symbol name='zpool_prop_column_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
535535
<elf-symbol name='zpool_prop_default_numeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -5809,7 +5809,8 @@
58095809
<enumerator name='POOL_SCRUB_NORMAL' value='0'/>
58105810
<enumerator name='POOL_SCRUB_PAUSE' value='1'/>
58115811
<enumerator name='POOL_SCRUB_FROM_LAST_TXG' value='2'/>
5812-
<enumerator name='POOL_SCRUB_FLAGS_END' value='3'/>
5812+
<enumerator name='POOL_SCRUB_RECENT_TXGS' value='3'/>
5813+
<enumerator name='POOL_SCRUB_FLAGS_END' value='4'/>
58135814
</enum-decl>
58145815
<typedef-decl name='pool_scrub_cmd_t' type-id='a1474cbd' id='b51cf3c2'/>
58155816
<enum-decl name='zpool_errata' id='d9abbf54'>
@@ -7839,7 +7840,7 @@
78397840
</data-member>
78407841
</class-decl>
78417842
<typedef-decl name='vdev_cbdata_t' type-id='b8006be8' id='a9679c94'/>
7842-
<class-decl name='zprop_get_cbdata' size-in-bits='832' is-struct='yes' visibility='default' id='f3d3c319'>
7843+
<class-decl name='zprop_get_cbdata' size-in-bits='960' is-struct='yes' visibility='default' id='f3d3c319'>
78437844
<data-member access='public' layout-offset-in-bits='0'>
78447845
<var-decl name='cb_sources' type-id='95e97e5e' visibility='default'/>
78457846
</data-member>
@@ -7858,6 +7859,9 @@
78587859
<data-member access='public' layout-offset-in-bits='448'>
78597860
<var-decl name='cb_first' type-id='c19b74c3' visibility='default'/>
78607861
</data-member>
7862+
<data-member access='public' layout-offset-in-bits='480'>
7863+
<var-decl name='cb_json' type-id='c19b74c3' visibility='default'/>
7864+
</data-member>
78617865
<data-member access='public' layout-offset-in-bits='512'>
78627866
<var-decl name='cb_proplist' type-id='3a9b2288' visibility='default'/>
78637867
</data-member>
@@ -7867,6 +7871,15 @@
78677871
<data-member access='public' layout-offset-in-bits='640'>
78687872
<var-decl name='cb_vdevs' type-id='a9679c94' visibility='default'/>
78697873
</data-member>
7874+
<data-member access='public' layout-offset-in-bits='832'>
7875+
<var-decl name='cb_jsobj' type-id='5ce45b60' visibility='default'/>
7876+
</data-member>
7877+
<data-member access='public' layout-offset-in-bits='896'>
7878+
<var-decl name='cb_json_as_int' type-id='c19b74c3' visibility='default'/>
7879+
</data-member>
7880+
<data-member access='public' layout-offset-in-bits='928'>
7881+
<var-decl name='cb_json_pool_key_guid' type-id='c19b74c3' visibility='default'/>
7882+
</data-member>
78707883
</class-decl>
78717884
<typedef-decl name='zprop_get_cbdata_t' type-id='f3d3c319' id='f3d87113'/>
78727885
<typedef-decl name='zprop_func' type-id='2e711a2a' id='1ec3747a'/>
@@ -7970,6 +7983,11 @@
79707983
<qualified-type-def type-id='d33f11cb' restrict='yes' id='5c53ba29'/>
79717984
<pointer-type-def type-id='ffa52b96' size-in-bits='64' id='76c8174b'/>
79727985
<pointer-type-def type-id='f3d87113' size-in-bits='64' id='0d2a0670'/>
7986+
<function-decl name='nvlist_print_json' visibility='default' binding='global' size-in-bits='64'>
7987+
<parameter type-id='822cd80b'/>
7988+
<parameter type-id='5ce45b60'/>
7989+
<return type-id='95e97e5e'/>
7990+
</function-decl>
79737991
<function-decl name='zpool_label_disk' mangled-name='zpool_label_disk' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_label_disk'>
79747992
<parameter type-id='b0382bb3'/>
79757993
<parameter type-id='4c81de99'/>
@@ -8077,6 +8095,11 @@
80778095
<parameter type-id='d33f11cb'/>
80788096
<return type-id='48b5725f'/>
80798097
</function-decl>
8098+
<function-decl name='putc' visibility='default' binding='global' size-in-bits='64'>
8099+
<parameter type-id='95e97e5e'/>
8100+
<parameter type-id='822cd80b'/>
8101+
<return type-id='95e97e5e'/>
8102+
</function-decl>
80808103
<function-decl name='puts' visibility='default' binding='global' size-in-bits='64'>
80818104
<parameter type-id='80f4b756'/>
80828105
<return type-id='95e97e5e'/>
@@ -8095,6 +8118,11 @@
80958118
<parameter type-id='95e97e5e'/>
80968119
<return type-id='48b5725f'/>
80978120
</function-decl>
8121+
<function-decl name='strspn' visibility='default' binding='global' size-in-bits='64'>
8122+
<parameter type-id='80f4b756'/>
8123+
<parameter type-id='80f4b756'/>
8124+
<return type-id='b59d7dce'/>
8125+
</function-decl>
80988126
<function-decl name='strnlen' visibility='default' binding='global' size-in-bits='64'>
80998127
<parameter type-id='80f4b756'/>
81008128
<parameter type-id='b59d7dce'/>
@@ -8294,12 +8322,12 @@
82948322
<function-decl name='zfs_version_print' mangled-name='zfs_version_print' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_version_print'>
82958323
<return type-id='95e97e5e'/>
82968324
</function-decl>
8297-
<function-decl name='use_color' mangled-name='use_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='use_color'>
8298-
<return type-id='95e97e5e'/>
8299-
</function-decl>
83008325
<function-decl name='zfs_version_nvlist' mangled-name='zfs_version_nvlist' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_version_nvlist'>
83018326
<return type-id='5ce45b60'/>
83028327
</function-decl>
8328+
<function-decl name='use_color' mangled-name='use_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='use_color'>
8329+
<return type-id='95e97e5e'/>
8330+
</function-decl>
83038331
<function-decl name='printf_color' mangled-name='printf_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='printf_color'>
83048332
<parameter type-id='80f4b756' name='color'/>
83058333
<parameter type-id='80f4b756' name='format'/>
@@ -8804,11 +8832,6 @@
88048832
<parameter type-id='78c01427'/>
88058833
<return type-id='13956559'/>
88068834
</function-decl>
8807-
<function-decl name='strspn' visibility='default' binding='global' size-in-bits='64'>
8808-
<parameter type-id='80f4b756'/>
8809-
<parameter type-id='80f4b756'/>
8810-
<return type-id='b59d7dce'/>
8811-
</function-decl>
88128835
<function-decl name='zfs_dirnamelen' mangled-name='zfs_dirnamelen' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_dirnamelen'>
88138836
<parameter type-id='80f4b756' name='path'/>
88148837
<return type-id='79a0948f'/>

man/man4/zfs.4

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,6 +1986,9 @@ working on a scrub between TXG flushes.
19861986
.It Sy zfs_scrub_error_blocks_per_txg Ns = Ns Sy 4096 Pq uint
19871987
Error blocks to be scrubbed in one txg.
19881988
.
1989+
.It Sy zfs_scrub_recent_txgs Ns = Ns Sy 256 Pq uint
1990+
Number of txgs to be considered as recent when performing a recent data scrub.
1991+
.
19891992
.It Sy zfs_scan_checkpoint_intval Ns = Ns Sy 7200 Ns s Po 2 hour Pc Pq uint
19901993
To preserve progress across reboots, the sequential scan algorithm periodically
19911994
needs to stop metadata scanning and issue all the verification I/O to disk.

man/man8/zpool-scrub.8

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
.Op Fl w
4141
.Op Fl e
4242
.Op Fl C
43+
.Op Fl R
4344
.Ar pool Ns
4445
.
4546
.Sh DESCRIPTION
@@ -119,6 +120,10 @@ resilvering, nor can it be run when a regular scrub is paused.
119120
Continue scrub from last saved txg (see zpool
120121
.Sy last_scrubbed_txg
121122
property).
123+
.It Fl R
124+
Scrub only recent data (this can be controlled by the
125+
.Sy zfs_scrub_recent_txgs
126+
parameter).
122127
.El
123128
.Sh EXAMPLES
124129
.Ss Example 1

module/zfs/dsl_scan.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ static int zfs_free_bpobj_enabled = 1;
239239
/* Error blocks to be scrubbed in one txg. */
240240
static uint_t zfs_scrub_error_blocks_per_txg = 1 << 12;
241241

242+
/* The number of TXGs should be scrubbed while scrubbing recent data. */
243+
uint_t zfs_scrub_recent_txgs = 256;
244+
242245
/* the order has to match pool_scan_type */
243246
static scan_cb_t *scan_funcs[POOL_SCAN_FUNCS] = {
244247
NULL,
@@ -5323,4 +5326,7 @@ ZFS_MODULE_PARAM(zfs, zfs_, resilver_disable_defer, INT, ZMOD_RW,
53235326

53245327
ZFS_MODULE_PARAM(zfs, zfs_, scrub_error_blocks_per_txg, UINT, ZMOD_RW,
53255328
"Error blocks to be scrubbed in one txg");
5329+
5330+
ZFS_MODULE_PARAM(zfs, zfs_, scrub_recent_txgs, UINT, ZMOD_RW,
5331+
"The number of TXGs should be scrubbed while scrubbing recent data");
53265332
/* END CSTYLED */

module/zfs/zfs_ioctl.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,6 +1722,16 @@ zfs_ioc_pool_scrub(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
17221722
} else if (scan_cmd == POOL_SCRUB_FROM_LAST_TXG) {
17231723
error = spa_scan_range(spa, scan_type,
17241724
spa_get_last_scrubbed_txg(spa), 0);
1725+
} else if (scan_cmd == POOL_SCRUB_RECENT_TXGS) {
1726+
uint64_t start;
1727+
1728+
start = 0;
1729+
if (spa_last_synced_txg(spa) > zfs_scrub_recent_txgs) {
1730+
start = spa_last_synced_txg(spa) -
1731+
zfs_scrub_recent_txgs;
1732+
}
1733+
1734+
error = spa_scan_range(spa, scan_type, start, 0);
17251735
} else {
17261736
error = spa_scan(spa, scan_type);
17271737
}

0 commit comments

Comments
 (0)