bcachefs: prepare journal buf put to handle pin put
authorBrian Foster <bfoster@redhat.com>
Fri, 15 Sep 2023 12:51:52 +0000 (08:51 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:10:14 +0000 (17:10 -0400)
bcachefs freeze testing has uncovered some raciness between journal
entry open/close and pin list reference count management. The
details of the problem are described in a separate patch. In
preparation for the associated fix, refactor the journal buffer put
path a bit to allow it to eventually handle dropping the pin list
reference currently held by an open journal entry.

Retain the journal write dispatch helper since the closure code is
inlined and we don't want to increase the amount of inline code in
the transaction commit path, but rename the function to reflect
the purpose of final processing of the journal buffer.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/journal.c
fs/bcachefs/journal.h

index 210a2b90bb508d8d1d25d9a6f9066fd901b891c8..be61d43458eb55c04e03d7404ba03d94cf95cbff 100644 (file)
@@ -134,7 +134,7 @@ journal_error_check_stuck(struct journal *j, int error, unsigned flags)
 
 /* journal entry close/open: */
 
-void __bch2_journal_buf_put(struct journal *j)
+void bch2_journal_buf_put_final(struct journal *j)
 {
        struct bch_fs *c = container_of(j, struct bch_fs, journal);
 
index 008a2e25a4fac93df681233b679c9fc6eaca95d0..0a53a214259492313a532b7ef49b799cdcb5ebb0 100644 (file)
@@ -252,9 +252,10 @@ static inline bool journal_entry_empty(struct jset *j)
        return true;
 }
 
-void __bch2_journal_buf_put(struct journal *);
-
-static inline void bch2_journal_buf_put(struct journal *j, unsigned idx)
+/*
+ * Drop reference on a buffer index and return true if the count has hit zero.
+ */
+static inline union journal_res_state journal_state_buf_put(struct journal *j, unsigned idx)
 {
        union journal_res_state s;
 
@@ -264,9 +265,20 @@ static inline void bch2_journal_buf_put(struct journal *j, unsigned idx)
                                    .buf2_count = idx == 2,
                                    .buf3_count = idx == 3,
                                    }).v, &j->reservations.counter);
+       return s;
+}
+
+void bch2_journal_buf_put_final(struct journal *);
 
-       if (!journal_state_count(s, idx) && idx == s.unwritten_idx)
-               __bch2_journal_buf_put(j);
+static inline void bch2_journal_buf_put(struct journal *j, unsigned idx)
+{
+       union journal_res_state s;
+
+       s = journal_state_buf_put(j, idx);
+       if (!journal_state_count(s, idx)) {
+               if (idx == s.unwritten_idx)
+                       bch2_journal_buf_put_final(j);
+       }
 }
 
 /*