summaryrefslogtreecommitdiff
path: root/libbcachefs/error.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-04-10 14:39:18 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-04-15 14:41:11 -0400
commit807b250927d9c6e829ddd1ff7eac57bf9b056dab (patch)
treec8c30549383c3b1950ac22fb927729bdd65234cf /libbcachefs/error.c
parent7f102ee83d83fd918783ca542fac1574f9b2c623 (diff)
Update bcachefs sources to 504729f99c bcachefs: Allow answering y or n to all fsck errors of given type
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'libbcachefs/error.c')
-rw-r--r--libbcachefs/error.c61
1 files changed, 56 insertions, 5 deletions
diff --git a/libbcachefs/error.c b/libbcachefs/error.c
index 1dae649f..b9076fee 100644
--- a/libbcachefs/error.c
+++ b/libbcachefs/error.c
@@ -65,10 +65,47 @@ 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 +198,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");