summaryrefslogtreecommitdiff
path: root/fs/bcachefs
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2023-03-22 15:27:58 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:59 +0300
commit349b1d832ba534b802a28f316e40128c54643c32 (patch)
treee8c727266703c98c8e36b2cce946110f1e55c640 /fs/bcachefs
parent3d86f13df67b554a7b27e28a4b144425710409bf (diff)
downloadlinux-349b1d832ba534b802a28f316e40128c54643c32.tar.xz
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: Brian Foster <bfoster@redhat.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs')
-rw-r--r--fs/bcachefs/btree_update.h1
-rw-r--r--fs/bcachefs/btree_update_leaf.c35
-rw-r--r--fs/bcachefs/recovery.c16
3 files changed, 38 insertions, 14 deletions
diff --git a/fs/bcachefs/btree_update.h b/fs/bcachefs/btree_update.h
index 63ff824a72da..5d5321dd42e8 100644
--- a/fs/bcachefs/btree_update.h
+++ b/fs/bcachefs/btree_update.h
@@ -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
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index da9840edc023..02d264b858ab 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -1924,22 +1924,45 @@ err:
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;
}
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index 6aa99f57a001..1b9a8329654e 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -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 @@ use_clean:
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 @@ use_clean:
}
}
- 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),