Skip to content

Commit 4538608

Browse files
author
TulsiJain
committed
rescrubbing only previously detected error block
Signed-off-by: TulsiJain <tulsi.jain@delphix.com>
1 parent d274ac5 commit 4538608

File tree

19 files changed

+699
-2
lines changed

19 files changed

+699
-2
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,7 @@ cscope.*
6262
*.orig
6363
*.log
6464
venv
65+
# Ignore Eclipse files
66+
/.cproject
67+
/.project
6568

cmd/zpool/zpool_main.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ static int zpool_do_split(int, char **);
100100

101101
static int zpool_do_initialize(int, char **);
102102
static int zpool_do_scrub(int, char **);
103+
static int zpool_do_rescrub(int, char **);
103104
static int zpool_do_resilver(int, char **);
104105
static int zpool_do_trim(int, char **);
105106

@@ -157,6 +158,7 @@ typedef enum {
157158
HELP_REMOVE,
158159
HELP_INITIALIZE,
159160
HELP_SCRUB,
161+
HELP_RESCRUB,
160162
HELP_RESILVER,
161163
HELP_TRIM,
162164
HELP_STATUS,
@@ -296,6 +298,7 @@ static zpool_command_t command_table[] = {
296298
{ "initialize", zpool_do_initialize, HELP_INITIALIZE },
297299
{ "resilver", zpool_do_resilver, HELP_RESILVER },
298300
{ "scrub", zpool_do_scrub, HELP_SCRUB },
301+
{ "rescrub", zpool_do_rescrub, HELP_RESCRUB },
299302
{ "trim", zpool_do_trim, HELP_TRIM },
300303
{ NULL },
301304
{ "import", zpool_do_import, HELP_IMPORT },
@@ -382,6 +385,8 @@ get_usage(zpool_help_t idx)
382385
"[<device> ...]\n"));
383386
case HELP_SCRUB:
384387
return (gettext("\tscrub [-s | -p] <pool> ...\n"));
388+
case HELP_RESCRUB:
389+
return (gettext("\trescrub [-s | -p] <pool> ...\n"));
385390
case HELP_RESILVER:
386391
return (gettext("\tresilver <pool> ...\n"));
387392
case HELP_TRIM:
@@ -6703,6 +6708,24 @@ scrub_callback(zpool_handle_t *zhp, void *data)
67036708
return (err != 0);
67046709
}
67056710

6711+
int
6712+
rescrub_callback(zpool_handle_t *zhp, void *data)
6713+
{
6714+
scrub_cbdata_t *cb = data;
6715+
int err;
6716+
6717+
/* Ignore faulted pools. */
6718+
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
6719+
(void) fprintf(stderr, gettext("cannot rescrub '%s': pool is "
6720+
"currently unavailable\n"), zpool_get_name(zhp));
6721+
return (1);
6722+
}
6723+
6724+
err = zpool_rescrub(zhp, cb->cb_type, cb->cb_scrub_cmd);
6725+
6726+
return (err != 0);
6727+
}
6728+
67066729
/*
67076730
* zpool scrub [-s | -p] <pool> ...
67086731
*
@@ -6754,6 +6777,62 @@ zpool_do_scrub(int argc, char **argv)
67546777
return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
67556778
}
67566779

6780+
/*
6781+
* zpool rescrub [-s | -p] <pool> ...
6782+
*
6783+
* -s Stop. Stops any in-progress rescrub.
6784+
* -p Pause. Pause in-progress rescrub.
6785+
*/
6786+
int
6787+
zpool_do_rescrub(int argc, char **argv)
6788+
{
6789+
int c;
6790+
scrub_cbdata_t cb;
6791+
6792+
cb.cb_type = POOL_RESCRUB;
6793+
cb.cb_scrub_cmd = POOL_RESCRUB_NORMAL;
6794+
6795+
/* check options */
6796+
while ((c = getopt(argc, argv, "sp")) != -1) {
6797+
switch (c) {
6798+
case 's':
6799+
if (cb.cb_scrub_cmd != POOL_RESCRUB_NORMAL) {
6800+
(void) fprintf(stderr, gettext("invalid option"
6801+
" combination: -s and -p are mutually"
6802+
" exclusive\n"));
6803+
usage(B_FALSE);
6804+
}
6805+
cb.cb_scrub_cmd = POOL_RESCRUB_STOP;
6806+
break;
6807+
case 'p':
6808+
if (cb.cb_scrub_cmd != POOL_RESCRUB_NORMAL) {
6809+
(void) fprintf(stderr, gettext("invalid option"
6810+
" combination: -s and -p are mutually"
6811+
" exclusive\n"));
6812+
usage(B_FALSE);
6813+
}
6814+
cb.cb_scrub_cmd = POOL_RESCRUB_PAUSE;
6815+
break;
6816+
case '?':
6817+
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
6818+
optopt);
6819+
usage(B_FALSE);
6820+
}
6821+
}
6822+
6823+
cb.cb_argc = argc;
6824+
cb.cb_argv = argv;
6825+
argc -= optind;
6826+
argv += optind;
6827+
6828+
if (argc < 1) {
6829+
(void) fprintf(stderr, gettext("missing pool name argument\n"));
6830+
usage(B_FALSE);
6831+
}
6832+
6833+
return (for_each_pool(argc, argv, B_TRUE, NULL, rescrub_callback, &cb));
6834+
}
6835+
67576836
/*
67586837
* zpool resilver <pool> ...
67596838
*

include/libzfs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,10 @@ typedef enum zfs_error {
125125
EZFS_THREADCREATEFAILED, /* thread create failed */
126126
EZFS_POSTSPLIT_ONLINE, /* onlining a disk after splitting it */
127127
EZFS_SCRUBBING, /* currently scrubbing */
128+
EZFS_RESCRUBBING, /* currently rescrubbing */
129+
EZFS_RESCRUB_PAUSED, /* rescrub currently paused */
128130
EZFS_NO_SCRUB, /* no active scrub */
131+
EZFS_NO_RESCRUB, /* no active rescrub */
129132
EZFS_DIFF, /* general failure of zfs diff */
130133
EZFS_DIFFDATA, /* bad zfs diff data */
131134
EZFS_POOLREADONLY, /* pool is in read-only mode */
@@ -273,6 +276,7 @@ typedef struct trimflags {
273276
* Functions to manipulate pool and vdev state
274277
*/
275278
extern int zpool_scan(zpool_handle_t *, pool_scan_func_t, pool_scrub_cmd_t);
279+
extern int zpool_rescrub(zpool_handle_t *, pool_scan_func_t, pool_scrub_cmd_t);
276280
extern int zpool_initialize(zpool_handle_t *, pool_initialize_func_t,
277281
nvlist_t *);
278282
extern int zpool_trim(zpool_handle_t *, pool_trim_func_t, nvlist_t *,

include/libzfs_core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ int lzc_reopen(const char *, boolean_t);
130130
int lzc_pool_checkpoint(const char *);
131131
int lzc_pool_checkpoint_discard(const char *);
132132

133+
int lzc_ioctl(zfs_ioc_t, const char *, nvlist_t *, nvlist_t **);
134+
133135
#ifdef __cplusplus
134136
}
135137
#endif

include/sys/dmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ typedef struct dmu_buf {
373373
#define DMU_POOL_DDT_STATS "DDT-statistics"
374374
#define DMU_POOL_CREATION_VERSION "creation_version"
375375
#define DMU_POOL_SCAN "scan"
376+
#define DMU_POOL_RESCRUB "rescrub"
376377
#define DMU_POOL_FREE_BPOBJ "free_bpobj"
377378
#define DMU_POOL_BPTREE_OBJ "bptree_obj"
378379
#define DMU_POOL_EMPTY_BPOBJ "empty_bpobj"

include/sys/dsl_scan.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include <sys/zfs_context.h>
3131
#include <sys/zio.h>
32+
#include <sys/zap.h>
3233
#include <sys/ddt.h>
3334
#include <sys/bplist.h>
3435

@@ -76,6 +77,18 @@ typedef enum dsl_scan_flags {
7677

7778
#define DSL_SCAN_FLAGS_MASK (DSF_VISIT_DS_AGAIN)
7879

80+
typedef struct dsl_rescrub_phys {
81+
uint64_t rescrub_func; /* pool_scan_func_t */
82+
uint64_t rescrub_state; /* dsl_scan_state_t */
83+
zap_cursor_t rescrub_cursor; /* zap cursor */
84+
uint64_t rescrub_start_time;
85+
uint64_t rescrub_end_time;
86+
uint64_t rescrub_to_examine; /* total blocks to be rescrubbed */
87+
uint64_t rescrub_examined; /* blocks remaining so far */
88+
uint64_t rescrub_errors; /* rescrub I/O error count */
89+
uint8_t rescrub_paused_flags; /* flag for paused */
90+
} dsl_rescrub_phys_t;
91+
7992
/*
8093
* Every pool will have one dsl_scan_t and this structure will contain
8194
* in-memory information about the scan and a pointer to the on-disk
@@ -153,6 +166,9 @@ typedef struct dsl_scan {
153166
dsl_scan_phys_t scn_phys_cached;
154167
avl_tree_t scn_queue; /* queue of datasets to scan */
155168
uint64_t scn_bytes_pending; /* outstanding data to issue */
169+
170+
/* members needed for syncing rescrub status to disk */
171+
dsl_rescrub_phys_t rescrub_phys; /* on disk representation of rescrub */
156172
} dsl_scan_t;
157173

158174
typedef struct dsl_scan_io_queue dsl_scan_io_queue_t;
@@ -166,6 +182,11 @@ int dsl_scan_cancel(struct dsl_pool *);
166182
int dsl_scan(struct dsl_pool *, pool_scan_func_t);
167183
boolean_t dsl_scan_scrubbing(const struct dsl_pool *dp);
168184
int dsl_scrub_set_pause_resume(const struct dsl_pool *dp, pool_scrub_cmd_t cmd);
185+
int dsl_rescrub_set_pause_resume(const struct dsl_pool *dp,
186+
pool_scrub_cmd_t cmd);
187+
int dsl_rescrub(struct dsl_pool *, pool_scan_func_t);
188+
void dsl_rescrub_sync(struct dsl_pool *, dmu_tx_t *);
189+
int dsl_rescrub_cancel(struct dsl_pool *);
169190
void dsl_resilver_restart(struct dsl_pool *, uint64_t txg);
170191
boolean_t dsl_scan_resilvering(struct dsl_pool *dp);
171192
boolean_t dsl_dataset_unstable(struct dsl_dataset *ds);

include/sys/fs/zfs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,7 @@ typedef enum pool_scan_func {
899899
POOL_SCAN_NONE,
900900
POOL_SCAN_SCRUB,
901901
POOL_SCAN_RESILVER,
902+
POOL_RESCRUB,
902903
POOL_SCAN_FUNCS
903904
} pool_scan_func_t;
904905

@@ -908,6 +909,9 @@ typedef enum pool_scan_func {
908909
typedef enum pool_scrub_cmd {
909910
POOL_SCRUB_NORMAL = 0,
910911
POOL_SCRUB_PAUSE,
912+
POOL_RESCRUB_NORMAL,
913+
POOL_RESCRUB_PAUSE,
914+
POOL_RESCRUB_STOP,
911915
POOL_SCRUB_FLAGS_END
912916
} pool_scrub_cmd_t;
913917

@@ -983,6 +987,7 @@ typedef enum dsl_scan_state {
983987
DSS_SCANNING,
984988
DSS_FINISHED,
985989
DSS_CANCELED,
990+
DSS_RESCRUBING,
986991
DSS_NUM_STATES
987992
} dsl_scan_state_t;
988993

@@ -1277,6 +1282,7 @@ typedef enum zfs_ioc {
12771282
ZFS_IOC_POOL_TRIM, /* 0x5a50 */
12781283
ZFS_IOC_REDACT, /* 0x5a51 */
12791284
ZFS_IOC_GET_BOOKMARK_PROPS, /* 0x5a52 */
1285+
ZFS_IOC_POOL_RESCRUB, /* 0x5a53 */
12801286

12811287
/*
12821288
* Linux - 3/64 numbers reserved.

include/sys/spa.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,11 @@ extern int spa_scan(spa_t *spa, pool_scan_func_t func);
858858
extern int spa_scan_stop(spa_t *spa);
859859
extern int spa_scrub_pause_resume(spa_t *spa, pool_scrub_cmd_t flag);
860860

861+
/* rescrubing */
862+
extern int spa_rescrub(spa_t *spa, pool_scan_func_t func);
863+
extern int spa_rescrub_stop(spa_t *spa);
864+
extern int spa_rescrub_pause_resume(spa_t *spa, pool_scrub_cmd_t flag);
865+
861866
/* spa syncing */
862867
extern void spa_sync(spa_t *spa, uint64_t txg); /* only for DMU use */
863868
extern void spa_sync_allpools(void);
@@ -1167,6 +1172,7 @@ extern void zfs_post_remove(spa_t *spa, vdev_t *vd);
11671172
extern void zfs_post_state_change(spa_t *spa, vdev_t *vd, uint64_t laststate);
11681173
extern void zfs_post_autoreplace(spa_t *spa, vdev_t *vd);
11691174
extern uint64_t spa_get_errlog_size(spa_t *spa);
1175+
extern uint64_t spa_get_last_errlog_size(spa_t *spa);
11701176
extern int spa_get_errlog(spa_t *spa, void *uaddr, size_t *count);
11711177
extern void spa_errlog_rotate(spa_t *spa);
11721178
extern void spa_errlog_drain(spa_t *spa);

include/sys/spa_impl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ struct spa {
284284
uint64_t spa_scan_pass_exam; /* examined bytes per pass */
285285
uint64_t spa_scan_pass_issued; /* issued bytes per pass */
286286

287+
uint64_t spa_scan_pass_rescrub_pause; /* rescrub pause time */
288+
uint64_t spa_scan_pass_rescrub_spent_paused; /* total paused */
287289
/*
288290
* We are in the middle of a resilver, and another resilver
289291
* is needed once this one completes. This is set iff any

include/sys/sysevent/eventdefs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ extern "C" {
123123
#define ESC_ZFS_TRIM_CANCEL "trim_cancel"
124124
#define ESC_ZFS_TRIM_RESUME "trim_resume"
125125
#define ESC_ZFS_TRIM_SUSPEND "trim_suspend"
126+
#define ESC_ZFS_RESCRUB_START "rescrub_start"
127+
#define ESC_ZFS_RESCRUB_FINISH "rescrub_finish"
128+
#define ESC_ZFS_RESCRUB_ABORT "rescrub_abort"
129+
#define ESC_ZFS_RESCRUB_RESUME "rescrub_resume"
130+
#define ESC_ZFS_RESCRUB_PAUSED "rescrub_paused"
126131

127132
/*
128133
* datalink subclass definitions.

0 commit comments

Comments
 (0)