bcachefs: New journal_entry_res mechanism
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 24 Jan 2019 21:50:48 +0000 (16:50 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:15 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/journal.c
fs/bcachefs/journal.h
fs/bcachefs/journal_types.h

index 310553bd53235fd7c1f451ffe7b41346b5e23270..dd10f1c993e5a6e40dfbef5f18247d41573ded7e 100644 (file)
@@ -64,11 +64,6 @@ static void bch2_journal_buf_init(struct journal *j)
        buf->data->u64s = 0;
 }
 
-static inline size_t journal_entry_u64s_reserve(struct journal_buf *buf)
-{
-       return BTREE_ID_NR * (JSET_KEYS_U64s + BKEY_EXTENT_U64s_MAX);
-}
-
 static inline bool journal_entry_empty(struct jset *j)
 {
        struct jset_entry *i;
@@ -130,7 +125,7 @@ static enum {
 
        j->prev_buf_sectors =
                vstruct_blocks_plus(buf->data, c->block_bits,
-                                   journal_entry_u64s_reserve(buf)) *
+                                   buf->u64s_reserved) *
                c->opts.block_size;
        BUG_ON(j->prev_buf_sectors > j->cur_buf_sectors);
 
@@ -225,6 +220,7 @@ static int journal_entry_open(struct journal *j)
                return sectors;
 
        buf->disk_sectors       = sectors;
+       buf->u64s_reserved      = j->entry_u64s_reserved;
 
        sectors = min_t(unsigned, sectors, buf->size >> 9);
        j->cur_buf_sectors      = sectors;
@@ -233,11 +229,7 @@ static int journal_entry_open(struct journal *j)
 
        /* Subtract the journal header */
        u64s -= sizeof(struct jset) / sizeof(u64);
-       /*
-        * Btree roots, prio pointers don't get added until right before we do
-        * the write:
-        */
-       u64s -= journal_entry_u64s_reserve(buf);
+       u64s -= buf->u64s_reserved;
        u64s  = max_t(ssize_t, 0L, u64s);
 
        BUG_ON(u64s >= JOURNAL_ENTRY_CLOSED_VAL);
@@ -437,6 +429,45 @@ int bch2_journal_res_get_slowpath(struct journal *j, struct journal_res *res,
        return ret;
 }
 
+/* journal_entry_res: */
+
+void bch2_journal_entry_res_resize(struct journal *j,
+                                  struct journal_entry_res *res,
+                                  unsigned new_u64s)
+{
+       union journal_res_state state;
+       int d = new_u64s - res->u64s;
+
+       spin_lock(&j->lock);
+
+       j->entry_u64s_reserved += d;
+       if (d <= 0)
+               goto out_unlock;
+
+       j->cur_entry_u64s -= d;
+       smp_mb();
+       state = READ_ONCE(j->reservations);
+
+       if (state.cur_entry_offset < JOURNAL_ENTRY_CLOSED_VAL &&
+           state.cur_entry_offset > j->cur_entry_u64s) {
+               j->cur_entry_u64s += d;
+               /*
+                * Not enough room in current journal entry, have to flush it:
+                */
+               __journal_entry_close(j);
+               goto out;
+       }
+
+       journal_cur_buf(j)->u64s_reserved += d;
+out_unlock:
+       spin_unlock(&j->lock);
+out:
+       res->u64s += d;
+       return;
+}
+
+/* journal flushing: */
+
 u64 bch2_journal_last_unwritten_seq(struct journal *j)
 {
        u64 seq;
@@ -1024,6 +1055,10 @@ int bch2_fs_journal_init(struct journal *j)
        j->write_delay_ms       = 1000;
        j->reclaim_delay_ms     = 100;
 
+       /* Btree roots: */
+       j->entry_u64s_reserved +=
+               BTREE_ID_NR * (JSET_KEYS_U64s + BKEY_EXTENT_U64s_MAX);
+
        atomic64_set(&j->reservations.counter,
                ((union journal_res_state)
                 { .cur_entry_offset = JOURNAL_ENTRY_CLOSED_VAL }).v);
index d9c094ba2ca0b2fc809b8ac98ec21f2f8c682e4e..6ef34bdae628a02496df9f5c45ea9cd2d39057cc 100644 (file)
@@ -333,6 +333,10 @@ out:
        return 0;
 }
 
+void bch2_journal_entry_res_resize(struct journal *,
+                                  struct journal_entry_res *,
+                                  unsigned);
+
 u64 bch2_journal_last_unwritten_seq(struct journal *);
 int bch2_journal_open_seq_async(struct journal *, u64, struct closure *);
 
index 51e453652d674c30a2a271554bd5da2bc5d43e7c..5f6d2320c5cd8fd2cd82ddaaa95a183a05f5551c 100644 (file)
@@ -24,6 +24,7 @@ struct journal_buf {
 
        unsigned                size;
        unsigned                disk_sectors;
+       unsigned                u64s_reserved;
        /* bloom filter: */
        unsigned long           has_inode[1024 / sizeof(unsigned long)];
 };
@@ -155,6 +156,9 @@ struct journal {
        u64                     seq_ondisk;
        u64                     last_seq_ondisk;
 
+       /* Reserved space in journal entry to be used just prior to write */
+       unsigned                entry_u64s_reserved;
+
        /*
         * FIFO of journal entries whose btree updates have not yet been
         * written out.
@@ -243,4 +247,11 @@ struct journal_device {
        struct closure          read;
 };
 
+/*
+ * journal_entry_res - reserve space in every journal entry:
+ */
+struct journal_entry_res {
+       unsigned                u64s;
+};
+
 #endif /* _BCACHEFS_JOURNAL_TYPES_H */