Skip to content

Commit f108d90

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 12e7144 commit f108d90

File tree

9 files changed

+60
-9
lines changed

9 files changed

+60
-9
lines changed

cmd/zpool/zpool_main.c

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ get_usage(zpool_help_t idx)
512512
return (gettext("\tinitialize [-c | -s | -u] [-w] <pool> "
513513
"[<device> ...]\n"));
514514
case HELP_SCRUB:
515-
return (gettext("\tscrub [-e | -s | -p | -C] [-w] "
515+
return (gettext("\tscrub [-e | -s | -p | -C | -R] [-w] "
516516
"<pool> ...\n"));
517517
case HELP_RESILVER:
518518
return (gettext("\tresilver <pool> ...\n"));
@@ -8413,13 +8413,14 @@ wait_callback(zpool_handle_t *zhp, void *data)
84138413
}
84148414

84158415
/*
8416-
* zpool scrub [-e | -s | -p | -C] [-w] <pool> ...
8416+
* zpool scrub [-e | -s | -p | -C | -R] [-w] <pool> ...
84178417
*
84188418
* -e Only scrub blocks in the error log.
84198419
* -s Stop. Stops any in-progress scrub.
84208420
* -p Pause. Pause in-progress scrub.
84218421
* -w Wait. Blocks until scrub has completed.
84228422
* -C Scrub from last saved txg.
8423+
* -R Scrub only recent data.
84238424
*/
84248425
int
84258426
zpool_do_scrub(int argc, char **argv)
@@ -8436,9 +8437,10 @@ zpool_do_scrub(int argc, char **argv)
84368437
boolean_t is_pause = B_FALSE;
84378438
boolean_t is_stop = B_FALSE;
84388439
boolean_t is_txg_continue = B_FALSE;
8440+
boolean_t is_recent_scrub = B_FALSE;
84398441

84408442
/* check options */
8441-
while ((c = getopt(argc, argv, "spweC")) != -1) {
8443+
while ((c = getopt(argc, argv, "spweCR")) != -1) {
84428444
switch (c) {
84438445
case 'e':
84448446
is_error_scrub = B_TRUE;
@@ -8455,6 +8457,9 @@ zpool_do_scrub(int argc, char **argv)
84558457
case 'C':
84568458
is_txg_continue = B_TRUE;
84578459
break;
8460+
case 'R':
8461+
is_recent_scrub = B_TRUE;
8462+
break;
84588463
case '?':
84598464
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
84608465
optopt);
@@ -8478,11 +8483,30 @@ zpool_do_scrub(int argc, char **argv)
84788483
(void) fprintf(stderr, gettext("invalid option "
84798484
"combination :-e and -C are mutually exclusive\n"));
84808485
usage(B_FALSE);
8486+
} else if (is_recent_scrub && is_txg_continue) {
8487+
(void) fprintf(stderr, gettext("invalid option "
8488+
"combination :-R and -C are mutually exclusive\n"));
8489+
usage(B_FALSE);
8490+
} else if (is_pause && is_recent_scrub) {
8491+
(void) fprintf(stderr, gettext("invalid option "
8492+
"combination :-p and -R are mutually exclusive\n"));
8493+
usage(B_FALSE);
8494+
} else if (is_stop && is_recent_scrub) {
8495+
(void) fprintf(stderr, gettext("invalid option "
8496+
"combination :-s and -R are mutually exclusive\n"));
8497+
usage(B_FALSE);
8498+
} else if (is_error_scrub && is_recent_scrub) {
8499+
(void) fprintf(stderr, gettext("invalid option "
8500+
"combination :-e and -R are mutually exclusive\n"));
8501+
usage(B_FALSE);
84818502
} else {
8482-
if (is_error_scrub)
8503+
if (is_error_scrub) {
84838504
cb.cb_type = POOL_SCAN_ERRORSCRUB;
8505+
}
84848506

8485-
if (is_pause) {
8507+
if (is_recent_scrub) {
8508+
cb.cb_scrub_cmd = POOL_SCRUB_RECENT_TXGS;
8509+
} else if (is_pause) {
84868510
cb.cb_scrub_cmd = POOL_SCRUB_PAUSE;
84878511
} else if (is_stop) {
84888512
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
@@ -1090,6 +1090,7 @@ typedef enum pool_scrub_cmd {
10901090
POOL_SCRUB_NORMAL = 0,
10911091
POOL_SCRUB_PAUSE,
10921092
POOL_SCRUB_FROM_LAST_TXG,
1093+
POOL_SCRUB_RECENT_TXGS,
10931094
POOL_SCRUB_FLAGS_END
10941095
} pool_scrub_cmd_t;
10951096

lib/libzfs/libzfs.abi

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3132,7 +3132,8 @@
31323132
<enumerator name='ZPOOL_PROP_DEDUP_TABLE_SIZE' value='36'/>
31333133
<enumerator name='ZPOOL_PROP_DEDUP_TABLE_QUOTA' value='37'/>
31343134
<enumerator name='ZPOOL_PROP_DEDUPCACHED' value='38'/>
3135-
<enumerator name='ZPOOL_NUM_PROPS' value='39'/>
3135+
<enumerator name='ZPOOL_PROP_LAST_SCRUBBED_TXG' value='39'/>
3136+
<enumerator name='ZPOOL_NUM_PROPS' value='40'/>
31363137
</enum-decl>
31373138
<typedef-decl name='zpool_prop_t' type-id='af1ba157' id='5d0c23fb'/>
31383139
<typedef-decl name='regoff_t' type-id='95e97e5e' id='54a2a2a8'/>
@@ -5985,7 +5986,8 @@
59855986
<enumerator name='POOL_SCRUB_NORMAL' value='0'/>
59865987
<enumerator name='POOL_SCRUB_PAUSE' value='1'/>
59875988
<enumerator name='POOL_SCRUB_FROM_LAST_TXG' value='2'/>
5988-
<enumerator name='POOL_SCRUB_FLAGS_END' value='3'/>
5989+
<enumerator name='POOL_SCRUB_RECENT_TXGS' value='3'/>
5990+
<enumerator name='POOL_SCRUB_FLAGS_END' value='4'/>
59895991
</enum-decl>
59905992
<typedef-decl name='pool_scrub_cmd_t' type-id='a1474cbd' id='b51cf3c2'/>
59915993
<enum-decl name='zpool_errata' id='d9abbf54'>

lib/libzfsbootenv/libzfsbootenv.abi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<abi-corpus version='2.0' architecture='elf-amd-x86_64' soname='libzfsbootenv.so.1'>
22
<elf-needed>
3-
<dependency name='libzfs.so.4'/>
3+
<dependency name='libzfs.so.6'/>
44
<dependency name='libnvpair.so.3'/>
55
<dependency name='libc.so.6'/>
66
</elf-needed>

man/man4/zfs.4

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

man/man8/zpool-scrub.8

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
.Sh SYNOPSIS
3737
.Nm zpool
3838
.Cm scrub
39-
.Op Ns Fl e | Ns Fl p | Fl s Ns | Fl C Ns
39+
.Op Ns Fl e | Ns Fl p | Fl s Ns | Fl C Ns | Fl R Ns
4040
.Op Fl w
4141
.Ar pool Ns
4242
.
@@ -117,6 +117,10 @@ resilvering, nor can it be run when a regular scrub is paused.
117117
Continue scrub from last saved txg (see zpool
118118
.Sy last_scrubbed_txg
119119
property).
120+
.It Fl R
121+
Scrub only recent data (this can be controlled by the
122+
.Sy zfs_scrub_recent_txgs
123+
parameter).
120124
.El
121125
.Sh EXAMPLES
122126
.Ss Example 1

module/zfs/dsl_scan.c

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

245+
/* The number of TXGs should be scrubbed while scrubbing recent data. */
246+
uint_t zfs_scrub_recent_txgs = 256;
247+
245248
/* the order has to match pool_scan_type */
246249
static scan_cb_t *scan_funcs[POOL_SCAN_FUNCS] = {
247250
NULL,
@@ -5349,4 +5352,7 @@ ZFS_MODULE_PARAM(zfs, zfs_, resilver_defer_percent, UINT, ZMOD_RW,
53495352

53505353
ZFS_MODULE_PARAM(zfs, zfs_, scrub_error_blocks_per_txg, UINT, ZMOD_RW,
53515354
"Error blocks to be scrubbed in one txg");
5355+
5356+
ZFS_MODULE_PARAM(zfs, zfs_, scrub_recent_txgs, UINT, ZMOD_RW,
5357+
"The number of TXGs should be scrubbed while scrubbing recent data");
53525358
/* END CSTYLED */

module/zfs/zfs_ioctl.c

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

0 commit comments

Comments
 (0)