Commit 349b1d83 authored by Brian Foster's avatar Brian Foster Committed by Kent Overstreet

bcachefs: use reservation for log messages during recovery

If we block on journal reservation attempting to log journal
messages during recovery, particularly for the first message(s)
before we start doing actual work, chances are the filesystem ends
up deadlocked.

Allow logged messages to use reserved journal space to mitigate this
problem. In the worst case where no space is available whatsoever,
this at least allows the fs to recognize that the journal is stuck
and fail the mount gracefully.
Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 3d86f13d
......@@ -95,6 +95,7 @@ void bch2_trans_commit_hook(struct btree_trans *,
int __bch2_trans_commit(struct btree_trans *, unsigned);
int bch2_fs_log_msg(struct bch_fs *, const char *, ...);
int bch2_journal_log_msg(struct bch_fs *, const char *, ...);
/**
* bch2_trans_commit - insert keys at given iterator positions
......
......@@ -1924,22 +1924,45 @@ static int __bch2_trans_log_msg(darray_u64 *entries, const char *fmt, va_list ar
return ret;
}
int bch2_fs_log_msg(struct bch_fs *c, const char *fmt, ...)
static int
__bch2_fs_log_msg(struct bch_fs *c, unsigned commit_flags, const char *fmt,
va_list args)
{
va_list args;
int ret;
va_start(args, fmt);
if (!test_bit(JOURNAL_STARTED, &c->journal.flags)) {
ret = __bch2_trans_log_msg(&c->journal.early_journal_entries, fmt, args);
} else {
ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_LAZY_RW,
ret = bch2_trans_do(c, NULL, NULL,
BTREE_INSERT_LAZY_RW|commit_flags,
__bch2_trans_log_msg(&trans.extra_journal_entries, fmt, args));
}
va_end(args);
return ret;
}
int bch2_fs_log_msg(struct bch_fs *c, const char *fmt, ...)
{
va_list args;
int ret;
va_start(args, fmt);
ret = __bch2_fs_log_msg(c, 0, fmt, args);
va_end(args);
return ret;
}
/*
* Use for logging messages during recovery to enable reserved space and avoid
* blocking.
*/
int bch2_journal_log_msg(struct bch_fs *c, const char *fmt, ...)
{
va_list args;
int ret;
va_start(args, fmt);
ret = __bch2_fs_log_msg(c, JOURNAL_WATERMARK_reserved, fmt, args);
va_end(args);
return ret;
}
......@@ -645,8 +645,8 @@ static int bch2_journal_replay(struct bch_fs *c, u64 start_seq, u64 end_seq)
journal_sort_seq_cmp, NULL);
if (keys->nr) {
ret = bch2_fs_log_msg(c, "Starting journal replay (%zu keys in entries %llu-%llu)",
keys->nr, start_seq, end_seq);
ret = bch2_journal_log_msg(c, "Starting journal replay (%zu keys in entries %llu-%llu)",
keys->nr, start_seq, end_seq);
if (ret)
goto err;
}
......@@ -680,7 +680,7 @@ static int bch2_journal_replay(struct bch_fs *c, u64 start_seq, u64 end_seq)
ret = bch2_journal_error(j);
if (keys->nr && !ret)
bch2_fs_log_msg(c, "journal replay finished");
bch2_journal_log_msg(c, "journal replay finished");
err:
kvfree(keys_sorted);
return ret;
......@@ -1244,8 +1244,8 @@ int bch2_fs_recovery(struct bch_fs *c)
journal_seq += 8;
if (blacklist_seq != journal_seq) {
ret = bch2_fs_log_msg(c, "blacklisting entries %llu-%llu",
blacklist_seq, journal_seq) ?:
ret = bch2_journal_log_msg(c, "blacklisting entries %llu-%llu",
blacklist_seq, journal_seq) ?:
bch2_journal_seq_blacklist_add(c,
blacklist_seq, journal_seq);
if (ret) {
......@@ -1254,14 +1254,14 @@ int bch2_fs_recovery(struct bch_fs *c)
}
}
ret = bch2_fs_log_msg(c, "starting journal at entry %llu, replaying %llu-%llu",
journal_seq, last_seq, blacklist_seq - 1) ?:
ret = bch2_journal_log_msg(c, "starting journal at entry %llu, replaying %llu-%llu",
journal_seq, last_seq, blacklist_seq - 1) ?:
bch2_fs_journal_start(&c->journal, journal_seq);
if (ret)
goto err;
if (c->opts.reconstruct_alloc)
bch2_fs_log_msg(c, "dropping alloc info");
bch2_journal_log_msg(c, "dropping alloc info");
/*
* Skip past versions that might have possibly been used (as nonces),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment