]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: btree_write_buffer_flush_seq() no longer closes journal
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 23 Apr 2024 06:18:18 +0000 (02:18 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 21 Dec 2024 06:36:19 +0000 (01:36 -0500)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_write_buffer.c
fs/bcachefs/journal.c
fs/bcachefs/journal.h

index 1bd26221f1564c8bbd6049e042fb9ec2a143dfea..49ce2d1e5c02022239332d1c76e8cdf7bc138702 100644 (file)
@@ -495,10 +495,6 @@ static int bch2_journal_keys_to_write_buffer(struct bch_fs *c, struct journal_bu
 
                entry->type = BCH_JSET_ENTRY_btree_keys;
        }
-
-       spin_lock(&c->journal.lock);
-       buf->need_flush_to_write_buffer = false;
-       spin_unlock(&c->journal.lock);
 out:
        ret = bch2_journal_keys_to_write_buffer_end(c, &dst) ?: ret;
        return ret;
@@ -508,11 +504,24 @@ static int fetch_wb_keys_from_journal(struct bch_fs *c, u64 max_seq)
 {
        struct journal *j = &c->journal;
        struct journal_buf *buf;
+       bool blocked;
        int ret = 0;
 
-       while (!ret && (buf = bch2_next_write_buffer_flush_journal_buf(j, max_seq))) {
+       while (!ret && (buf = bch2_next_write_buffer_flush_journal_buf(j, max_seq, &blocked))) {
                ret = bch2_journal_keys_to_write_buffer(c, buf);
+
+               if (!blocked && !ret) {
+                       spin_lock(&j->lock);
+                       buf->need_flush_to_write_buffer = false;
+                       spin_unlock(&j->lock);
+               }
+
                mutex_unlock(&j->buf_lock);
+
+               if (blocked) {
+                       bch2_journal_unblock(j);
+                       break;
+               }
        }
 
        return ret;
index bfbb1ac60c3d53971b98721b5193361547cf2f41..699db0d0749acd10e0dba963c04ad2db1c843b5b 100644 (file)
@@ -908,6 +908,8 @@ static void __bch2_journal_block(struct journal *j)
                        new.v = old.v;
                        new.cur_entry_offset = JOURNAL_ENTRY_BLOCKED_VAL;
                } while (!atomic64_try_cmpxchg(&j->reservations.counter, &old.v, new.v));
+
+               journal_cur_buf(j)->data->u64s = cpu_to_le32(old.cur_entry_offset);
        }
 }
 
@@ -920,7 +922,8 @@ void bch2_journal_block(struct journal *j)
        journal_quiesce(j);
 }
 
-static struct journal_buf *__bch2_next_write_buffer_flush_journal_buf(struct journal *j, u64 max_seq)
+static struct journal_buf *__bch2_next_write_buffer_flush_journal_buf(struct journal *j,
+                                               u64 max_seq, bool *blocked)
 {
        struct journal_buf *ret = NULL;
 
@@ -937,13 +940,17 @@ static struct journal_buf *__bch2_next_write_buffer_flush_journal_buf(struct jou
                struct journal_buf *buf = j->buf + idx;
 
                if (buf->need_flush_to_write_buffer) {
-                       if (seq == journal_cur_seq(j))
-                               __journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL, true);
-
                        union journal_res_state s;
                        s.v = atomic64_read_acquire(&j->reservations.counter);
 
-                       ret = journal_state_count(s, idx)
+                       unsigned open = seq == journal_cur_seq(j) && __journal_entry_is_open(s);
+
+                       if (open && !*blocked) {
+                               __bch2_journal_block(j);
+                               *blocked = true;
+                       }
+
+                       ret = journal_state_count(s, idx) > open
                                ? ERR_PTR(-EAGAIN)
                                : buf;
                        break;
@@ -956,11 +963,17 @@ static struct journal_buf *__bch2_next_write_buffer_flush_journal_buf(struct jou
        return ret;
 }
 
-struct journal_buf *bch2_next_write_buffer_flush_journal_buf(struct journal *j, u64 max_seq)
+struct journal_buf *bch2_next_write_buffer_flush_journal_buf(struct journal *j,
+                                                            u64 max_seq, bool *blocked)
 {
        struct journal_buf *ret;
+       *blocked = false;
+
+       wait_event(j->wait, (ret = __bch2_next_write_buffer_flush_journal_buf(j,
+                                               max_seq, blocked)) != ERR_PTR(-EAGAIN));
+       if (IS_ERR_OR_NULL(ret) && *blocked)
+               bch2_journal_unblock(j);
 
-       wait_event(j->wait, (ret = __bch2_next_write_buffer_flush_journal_buf(j, max_seq)) != ERR_PTR(-EAGAIN));
        return ret;
 }
 
index 6d3c839bbbefcc0254ff1394bd39003529e79ba9..71a50846967f6d84f2808a6a35ee45a98e6dc4c8 100644 (file)
@@ -425,7 +425,7 @@ static inline void bch2_journal_set_replay_done(struct journal *j)
 
 void bch2_journal_unblock(struct journal *);
 void bch2_journal_block(struct journal *);
-struct journal_buf *bch2_next_write_buffer_flush_journal_buf(struct journal *j, u64 max_seq);
+struct journal_buf *bch2_next_write_buffer_flush_journal_buf(struct journal *, u64, bool *);
 
 void __bch2_journal_debug_to_text(struct printbuf *, struct journal *);
 void bch2_journal_debug_to_text(struct printbuf *, struct journal *);