bcachefs: Allow answering y or n to all fsck errors of given type
This changes the ask_yn() function used by fsck to accept Y or N, meaning yes or no for all errors of a given type. With this, the user can be prompted only for distinct error types - useful when a filesystem has lots of errors. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
6b9857b208
commit
853b7393c2
@ -65,10 +65,51 @@ void bch2_io_error(struct bch_dev *ca)
|
||||
//queue_work(system_long_wq, &ca->io_error_work);
|
||||
}
|
||||
|
||||
enum ask_yn {
|
||||
YN_NO,
|
||||
YN_YES,
|
||||
YN_ALLNO,
|
||||
YN_ALLYES,
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#define ask_yn() false
|
||||
#define bch2_fsck_ask_yn() YN_NO
|
||||
#else
|
||||
|
||||
#include "tools-util.h"
|
||||
|
||||
enum ask_yn bch2_fsck_ask_yn(void)
|
||||
{
|
||||
char *buf = NULL;
|
||||
size_t buflen = 0;
|
||||
bool ret;
|
||||
|
||||
while (true) {
|
||||
fputs(" (y,n,Y,N) ", stdout);
|
||||
fflush(stdout);
|
||||
|
||||
if (getline(&buf, &buflen, stdin) < 0)
|
||||
die("error reading from standard input");
|
||||
|
||||
if (strlen(buf) != 1)
|
||||
continue;
|
||||
|
||||
switch (buf[0]) {
|
||||
case 'n':
|
||||
return YN_NO;
|
||||
case 'y':
|
||||
return YN_YES;
|
||||
case 'N':
|
||||
return YN_ALLNO;
|
||||
case 'Y':
|
||||
return YN_ALLYES;
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static struct fsck_err_state *fsck_err_get(struct bch_fs *c, const char *fmt)
|
||||
@ -161,14 +202,28 @@ int bch2_fsck_err(struct bch_fs *c, unsigned flags, const char *fmt, ...)
|
||||
prt_str(out, ", exiting");
|
||||
ret = -BCH_ERR_fsck_errors_not_fixed;
|
||||
} else if (flags & FSCK_CAN_FIX) {
|
||||
if (c->opts.fix_errors == FSCK_OPT_ASK) {
|
||||
int fix = s && s->fix
|
||||
? s->fix
|
||||
: c->opts.fix_errors;
|
||||
|
||||
if (fix == FSCK_OPT_ASK) {
|
||||
int ask;
|
||||
|
||||
prt_str(out, ": fix?");
|
||||
bch2_print_string_as_lines(KERN_ERR, out->buf);
|
||||
print = false;
|
||||
ret = ask_yn()
|
||||
|
||||
ask = bch2_fsck_ask_yn();
|
||||
|
||||
if (ask >= YN_ALLNO && s)
|
||||
s->fix = ask == YN_ALLNO
|
||||
? FSCK_OPT_NO
|
||||
: FSCK_OPT_YES;
|
||||
|
||||
ret = ask & 1
|
||||
? -BCH_ERR_fsck_fix
|
||||
: -BCH_ERR_fsck_ignore;
|
||||
} else if (c->opts.fix_errors == FSCK_OPT_YES ||
|
||||
} else if (fix == FSCK_OPT_YES ||
|
||||
(c->opts.nochanges &&
|
||||
!(flags & FSCK_CAN_IGNORE))) {
|
||||
prt_str(out, ", fixing");
|
||||
|
@ -104,6 +104,7 @@ struct fsck_err_state {
|
||||
u64 nr;
|
||||
bool ratelimited;
|
||||
int ret;
|
||||
int fix;
|
||||
char *last_msg;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user