// SPDX-License-Identifier: GPL-2.0
#include "bcachefs.h"
#include "error.h"
-#include "io.h"
#include "super.h"
#define FSCK_ERR_RATELIMIT_NR 10
void bch2_topology_error(struct bch_fs *c)
{
- if (!test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags))
- return;
-
set_bit(BCH_FS_TOPOLOGY_ERROR, &c->flags);
if (test_bit(BCH_FS_FSCK_DONE, &c->flags))
bch2_inconsistent_error(c);
bool ret;
while (true) {
- fputs(" (y,n,Y,N) ", stdout);
+ fputs(" (y,n, or Y,N for all errors of this type) ", stdout);
fflush(stdout);
if (getline(&buf, &buflen, stdin) < 0)
die("error reading from standard input");
+ strim(buf);
if (strlen(buf) != 1)
continue;
mutex_lock(&c->fsck_error_lock);
s = fsck_err_get(c, fmt);
if (s) {
+ /*
+ * We may be called multiple times for the same error on
+ * transaction restart - this memoizes instead of asking the user
+ * multiple times for the same error:
+ */
if (s->last_msg && !strcmp(buf.buf, s->last_msg)) {
ret = s->ret;
mutex_unlock(&c->fsck_error_lock);
prt_str(out, ", continuing");
ret = -BCH_ERR_fsck_ignore;
}
- } else if (c->opts.fix_errors == FSCK_OPT_EXIT) {
+ } else if (c->opts.fix_errors == FSCK_FIX_exit) {
prt_str(out, ", exiting");
ret = -BCH_ERR_fsck_errors_not_fixed;
} else if (flags & FSCK_CAN_FIX) {
? s->fix
: c->opts.fix_errors;
- if (fix == FSCK_OPT_ASK) {
+ if (fix == FSCK_FIX_ask) {
int ask;
prt_str(out, ": fix?");
if (ask >= YN_ALLNO && s)
s->fix = ask == YN_ALLNO
- ? FSCK_OPT_NO
- : FSCK_OPT_YES;
+ ? FSCK_FIX_no
+ : FSCK_FIX_yes;
ret = ask & 1
? -BCH_ERR_fsck_fix
: -BCH_ERR_fsck_ignore;
- } else if (fix == FSCK_OPT_YES ||
+ } else if (fix == FSCK_FIX_yes ||
(c->opts.nochanges &&
!(flags & FSCK_CAN_IGNORE))) {
prt_str(out, ", fixing");
}
if (ret == -BCH_ERR_fsck_ignore &&
- (c->opts.fix_errors == FSCK_OPT_EXIT ||
+ (c->opts.fix_errors == FSCK_FIX_exit ||
!(flags & FSCK_CAN_IGNORE)))
ret = -BCH_ERR_fsck_errors_not_fixed;