mirror of
https://github.com/torvalds/linux.git
synced 2025-11-02 17:49:03 +02:00
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
2 changed files with 60 additions and 4 deletions
|
|
@ -65,10 +65,51 @@ void bch2_io_error(struct bch_dev *ca)
|
||||||
//queue_work(system_long_wq, &ca->io_error_work);
|
//queue_work(system_long_wq, &ca->io_error_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ask_yn {
|
||||||
|
YN_NO,
|
||||||
|
YN_YES,
|
||||||
|
YN_ALLNO,
|
||||||
|
YN_ALLYES,
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
#define ask_yn() false
|
#define bch2_fsck_ask_yn() YN_NO
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include "tools-util.h"
|
#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
|
#endif
|
||||||
|
|
||||||
static struct fsck_err_state *fsck_err_get(struct bch_fs *c, const char *fmt)
|
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");
|
prt_str(out, ", exiting");
|
||||||
ret = -BCH_ERR_fsck_errors_not_fixed;
|
ret = -BCH_ERR_fsck_errors_not_fixed;
|
||||||
} else if (flags & FSCK_CAN_FIX) {
|
} 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?");
|
prt_str(out, ": fix?");
|
||||||
bch2_print_string_as_lines(KERN_ERR, out->buf);
|
bch2_print_string_as_lines(KERN_ERR, out->buf);
|
||||||
print = false;
|
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_fix
|
||||||
: -BCH_ERR_fsck_ignore;
|
: -BCH_ERR_fsck_ignore;
|
||||||
} else if (c->opts.fix_errors == FSCK_OPT_YES ||
|
} else if (fix == FSCK_OPT_YES ||
|
||||||
(c->opts.nochanges &&
|
(c->opts.nochanges &&
|
||||||
!(flags & FSCK_CAN_IGNORE))) {
|
!(flags & FSCK_CAN_IGNORE))) {
|
||||||
prt_str(out, ", fixing");
|
prt_str(out, ", fixing");
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ struct fsck_err_state {
|
||||||
u64 nr;
|
u64 nr;
|
||||||
bool ratelimited;
|
bool ratelimited;
|
||||||
int ret;
|
int ret;
|
||||||
|
int fix;
|
||||||
char *last_msg;
|
char *last_msg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue