bcachefs: Unlock trans when waiting for user input in fsck
We can't hold locks while waiting for user input, that's a deadlock. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
747d1d6c7e
commit
889fb3dc5d
@ -99,7 +99,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;
|
||||
|
||||
@ -109,17 +109,33 @@ static enum ask_yn bch2_fsck_ask_yn(struct bch_fs *c)
|
||||
if (!stdio)
|
||||
return YN_NO;
|
||||
|
||||
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, &line);
|
||||
if (r < 0) {
|
||||
ret = YN_NO;
|
||||
break;
|
||||
}
|
||||
|
||||
darray_last(line) = '\0';
|
||||
} while ((ret = parse_yn_response(line.data)) < 0);
|
||||
|
||||
@ -130,7 +146,7 @@ static enum ask_yn bch2_fsck_ask_yn(struct bch_fs *c)
|
||||
|
||||
#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;
|
||||
@ -326,7 +342,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
|
||||
|
Loading…
x
Reference in New Issue
Block a user