]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bcachefs: bch2_journal_meta() takes ref on c->writes
authorKent Overstreet <kent.overstreet@linux.dev>
Sat, 12 Oct 2024 02:50:48 +0000 (22:50 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 21 Dec 2024 06:36:15 +0000 (01:36 -0500)
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>
fs/bcachefs/bcachefs.h
fs/bcachefs/journal.c
fs/bcachefs/recovery.c

index fbd89f91625d0ee492988da5c0fce2568062d884..d4d95ef6791f3d300de5b2d25bd772713283de75 100644 (file)
@@ -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)                                                      \
index 2dc0d60c174509f20fdf1d89685c7074bf93c375..2cf8f24d50cc2b30dff04c7f3cbaf5861b5b0999 100644 (file)
@@ -831,19 +831,14 @@ out:
        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);
index bc2fd174bb329b4ce09a0500d7ba533257e0f44f..43169818909098fcc1c72765708955fc9d6b37c5 100644 (file)
@@ -910,11 +910,9 @@ use_clean:
        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: */