summaryrefslogtreecommitdiff
path: root/libbcachefs/error.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-06-03 17:03:54 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2024-06-03 20:08:06 -0400
commit7d79fba1af3d41b148009d3dc76d813b07f01f69 (patch)
treebee9ba49d247a1c74d1c1e7c9c14b37a243bba89 /libbcachefs/error.c
parentd456f9e97aebe649a59cc2858d5f28749b77d1d0 (diff)
Update bcachefs sources to f81dc88f0c80 bcachefs: bch2_btree_insert() - add btree iter flags
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'libbcachefs/error.c')
-rw-r--r--libbcachefs/error.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/libbcachefs/error.c b/libbcachefs/error.c
index c66eeffc..285b7251 100644
--- a/libbcachefs/error.c
+++ b/libbcachefs/error.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include "bcachefs.h"
+#include "btree_iter.h"
#include "error.h"
#include "journal.h"
#include "recovery_passes.h"
@@ -97,7 +98,7 @@ static enum ask_yn parse_yn_response(char *buf)
}
#ifdef __KERNEL__
-static enum ask_yn bch2_fsck_ask_yn(struct bch_fs *c)
+static enum ask_yn bch2_fsck_ask_yn(struct bch_fs *c, struct btree_trans *trans)
{
struct stdio_redirect *stdio = c->stdio;
@@ -107,25 +108,44 @@ static enum ask_yn bch2_fsck_ask_yn(struct bch_fs *c)
if (!stdio)
return YN_NO;
- char buf[100];
+ if (trans)
+ bch2_trans_unlock(trans);
+
+ unsigned long unlock_long_at = trans ? jiffies + HZ * 2 : 0;
+ darray_char line = {};
int ret;
do {
+ unsigned long t;
bch2_print(c, " (y,n, or Y,N for all errors of this type) ");
+rewait:
+ t = unlock_long_at
+ ? max_t(long, unlock_long_at - jiffies, 0)
+ : MAX_SCHEDULE_TIMEOUT;
+
+ int r = bch2_stdio_redirect_readline_timeout(stdio, &line, t);
+ if (r == -ETIME) {
+ bch2_trans_unlock_long(trans);
+ unlock_long_at = 0;
+ goto rewait;
+ }
- int r = bch2_stdio_redirect_readline(stdio, buf, sizeof(buf) - 1);
- if (r < 0)
- return YN_NO;
- buf[r] = '\0';
- } while ((ret = parse_yn_response(buf)) < 0);
+ if (r < 0) {
+ ret = YN_NO;
+ break;
+ }
+ darray_last(line) = '\0';
+ } while ((ret = parse_yn_response(line.data)) < 0);
+
+ darray_exit(&line);
return ret;
}
#else
#include "tools-util.h"
-static enum ask_yn bch2_fsck_ask_yn(struct bch_fs *c)
+static enum ask_yn bch2_fsck_ask_yn(struct bch_fs *c, struct btree_trans *trans)
{
char *buf = NULL;
size_t buflen = 0;
@@ -191,7 +211,8 @@ static void prt_actioning(struct printbuf *out, const char *action)
prt_str(out, "ing");
}
-int bch2_fsck_err(struct bch_fs *c,
+int __bch2_fsck_err(struct bch_fs *c,
+ struct btree_trans *trans,
enum bch_fsck_flags flags,
enum bch_sb_error_id err,
const char *fmt, ...)
@@ -203,6 +224,11 @@ int bch2_fsck_err(struct bch_fs *c,
int ret = -BCH_ERR_fsck_ignore;
const char *action_orig = "fix?", *action = action_orig;
+ if (!c)
+ c = trans->c;
+
+ WARN_ON(!trans && bch2_current_has_btree_trans(c));
+
if ((flags & FSCK_CAN_FIX) &&
test_bit(err, c->sb.errors_silent))
return -BCH_ERR_fsck_fix;
@@ -297,7 +323,15 @@ int bch2_fsck_err(struct bch_fs *c,
bch2_print_string_as_lines(KERN_ERR, out->buf);
print = false;
- int ask = bch2_fsck_ask_yn(c);
+ int ask = bch2_fsck_ask_yn(c, trans);
+
+ if (trans) {
+ ret = bch2_trans_relock(trans);
+ if (ret) {
+ mutex_unlock(&c->fsck_error_msgs_lock);
+ goto err;
+ }
+ }
if (ask >= YN_ALLNO && s)
s->fix = ask == YN_ALLNO