113 lines
3.5 KiB
Diff
113 lines
3.5 KiB
Diff
From a99869f0b74e8ced83ece54c3f1645363fe8214c Mon Sep 17 00:00:00 2001
|
|
From: Kent Overstreet <kent.overstreet@linux.dev>
|
|
Date: Fri, 11 Oct 2024 22:50:48 -0400
|
|
Subject: [PATCH 028/233] bcachefs: bch2_journal_meta() takes ref on c->writes
|
|
Content-Type: text/plain; charset="utf-8"
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
This part of addressing
|
|
https://github.com/koverstreet/bcachefs/issues/656
|
|
|
|
where we're getting stuck in bch2_journal_meta() in the dump tool.
|
|
|
|
We shouldn't be invoking the journal without a ref on c->writes (if
|
|
we're not RW), and there's no reason for the dump tool to be going
|
|
read-write.
|
|
|
|
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
|
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
|
---
|
|
fs/bcachefs/bcachefs.h | 1 +
|
|
fs/bcachefs/journal.c | 27 +++++++++++++++++----------
|
|
fs/bcachefs/recovery.c | 4 +---
|
|
3 files changed, 19 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
|
|
index fbd89f91625d..d4d95ef6791f 100644
|
|
--- a/fs/bcachefs/bcachefs.h
|
|
+++ b/fs/bcachefs/bcachefs.h
|
|
@@ -688,6 +688,7 @@ struct btree_trans_buf {
|
|
((subvol_inum) { BCACHEFS_ROOT_SUBVOL, BCACHEFS_ROOT_INO })
|
|
|
|
#define BCH_WRITE_REFS() \
|
|
+ x(journal) \
|
|
x(trans) \
|
|
x(write) \
|
|
x(promote) \
|
|
diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c
|
|
index 2dc0d60c1745..2cf8f24d50cc 100644
|
|
--- a/fs/bcachefs/journal.c
|
|
+++ b/fs/bcachefs/journal.c
|
|
@@ -831,19 +831,14 @@ bool bch2_journal_noflush_seq(struct journal *j, u64 seq)
|
|
return ret;
|
|
}
|
|
|
|
-int bch2_journal_meta(struct journal *j)
|
|
+static int __bch2_journal_meta(struct journal *j)
|
|
{
|
|
- struct journal_buf *buf;
|
|
- struct journal_res res;
|
|
- int ret;
|
|
-
|
|
- memset(&res, 0, sizeof(res));
|
|
-
|
|
- ret = bch2_journal_res_get(j, &res, jset_u64s(0), 0);
|
|
+ struct journal_res res = {};
|
|
+ int ret = bch2_journal_res_get(j, &res, jset_u64s(0), 0);
|
|
if (ret)
|
|
return ret;
|
|
|
|
- buf = j->buf + (res.seq & JOURNAL_BUF_MASK);
|
|
+ struct journal_buf *buf = j->buf + (res.seq & JOURNAL_BUF_MASK);
|
|
buf->must_flush = true;
|
|
|
|
if (!buf->flush_time) {
|
|
@@ -856,6 +851,18 @@ int bch2_journal_meta(struct journal *j)
|
|
return bch2_journal_flush_seq(j, res.seq, TASK_UNINTERRUPTIBLE);
|
|
}
|
|
|
|
+int bch2_journal_meta(struct journal *j)
|
|
+{
|
|
+ struct bch_fs *c = container_of(j, struct bch_fs, journal);
|
|
+
|
|
+ if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_journal))
|
|
+ return -EROFS;
|
|
+
|
|
+ int ret = __bch2_journal_meta(j);
|
|
+ bch2_write_ref_put(c, BCH_WRITE_REF_journal);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
/* block/unlock the journal: */
|
|
|
|
void bch2_journal_unblock(struct journal *j)
|
|
@@ -1193,7 +1200,7 @@ void bch2_fs_journal_stop(struct journal *j)
|
|
* Always write a new journal entry, to make sure the clock hands are up
|
|
* to date (and match the superblock)
|
|
*/
|
|
- bch2_journal_meta(j);
|
|
+ __bch2_journal_meta(j);
|
|
|
|
journal_quiesce(j);
|
|
cancel_delayed_work_sync(&j->write_work);
|
|
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
|
|
index bc2fd174bb32..431698189090 100644
|
|
--- a/fs/bcachefs/recovery.c
|
|
+++ b/fs/bcachefs/recovery.c
|
|
@@ -910,11 +910,9 @@ int bch2_fs_recovery(struct bch_fs *c)
|
|
set_bit(BCH_FS_accounting_replay_done, &c->flags);
|
|
|
|
/* fsync if we fixed errors */
|
|
- if (test_bit(BCH_FS_errors_fixed, &c->flags) &&
|
|
- bch2_write_ref_tryget(c, BCH_WRITE_REF_fsync)) {
|
|
+ if (test_bit(BCH_FS_errors_fixed, &c->flags)) {
|
|
bch2_journal_flush_all_pins(&c->journal);
|
|
bch2_journal_meta(&c->journal);
|
|
- bch2_write_ref_put(c, BCH_WRITE_REF_fsync);
|
|
}
|
|
|
|
/* If we fixed errors, verify that fs is actually clean now: */
|
|
--
|
|
2.45.2
|
|
|