]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bcachefs: btree_trans_subbuf
authorKent Overstreet <kent.overstreet@linux.dev>
Sat, 17 May 2025 00:23:58 +0000 (20:23 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 22 May 2025 00:15:06 +0000 (20:15 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs.h
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_trans_commit.c
fs/bcachefs/btree_types.h
fs/bcachefs/btree_update.c
fs/bcachefs/btree_update.h
fs/bcachefs/disk_accounting.c
fs/bcachefs/disk_accounting.h

index b58fad743fc455266ed483299f57925d38ae3b43..3077f15439cd095e15c36bccf1995f453e7ebef4 100644 (file)
@@ -712,7 +712,6 @@ struct btree_transaction_stats {
        struct bch2_time_stats  lock_hold_times;
        struct mutex            lock;
        unsigned                nr_max_paths;
-       unsigned                journal_entries_size;
        unsigned                max_mem;
 #ifdef CONFIG_BCACHEFS_TRANS_KMALLOC_TRACE
        darray_trans_kmalloc_trace trans_kmalloc_trace;
index e0c1e873c886d5a643f20fd8184b981bc47cbdf4..0f0b80c8c29a76767658c74af016963321f1c472 100644 (file)
@@ -1499,7 +1499,7 @@ void bch2_trans_updates_to_text(struct printbuf *buf, struct btree_trans *trans)
                prt_newline(buf);
        }
 
-       for (struct jset_entry *e = trans->journal_entries;
+       for (struct jset_entry *e = btree_trans_journal_entries_start(trans);
             e != btree_trans_journal_entries_top(trans);
             e = vstruct_next(e)) {
                bch2_journal_entry_to_text(buf, trans->c, e);
@@ -3280,7 +3280,6 @@ u32 bch2_trans_begin(struct btree_trans *trans)
 
        trans->restart_count++;
        trans->mem_top                  = 0;
-       trans->journal_entries          = NULL;
 
        trans_for_each_path(trans, path, i) {
                path->should_be_locked = false;
@@ -3438,7 +3437,6 @@ got_trans:
                }
 
                trans->nr_paths_max = s->nr_max_paths;
-               trans->journal_entries_size = s->journal_entries_size;
        }
 
        trans->srcu_idx         = srcu_read_lock(&c->btree_trans_barrier);
index 7e17df1df7f15923cd869fcea2422b4c78d9478e..abbecddb18ee9320e302613a1ada9d164119b7af 100644 (file)
@@ -663,15 +663,16 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
                h = h->next;
        }
 
-       struct jset_entry *entry = trans->journal_entries;
+       struct jset_entry *entry;
 
        percpu_down_read(&c->mark_lock);
-       for (entry = trans->journal_entries;
-            entry != (void *) ((u64 *) trans->journal_entries + trans->journal_entries_u64s);
+       for (entry = btree_trans_journal_entries_start(trans);
+            entry != btree_trans_journal_entries_top(trans);
             entry = vstruct_next(entry))
                if (entry->type == BCH_JSET_ENTRY_write_buffer_keys &&
                    entry->start->k.type == KEY_TYPE_accounting) {
-                       ret = bch2_accounting_trans_commit_hook(trans, bkey_i_to_accounting(entry->start), flags);
+                       ret = bch2_accounting_trans_commit_hook(trans,
+                                               bkey_i_to_accounting(entry->start), flags);
                        if (ret)
                                goto revert_fs_usage;
                }
@@ -698,8 +699,8 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
        if (!(flags & BCH_TRANS_COMMIT_no_journal_res))
                validate_context.flags = BCH_VALIDATE_write|BCH_VALIDATE_commit;
 
-       for (struct jset_entry *i = trans->journal_entries;
-            i != (void *) ((u64 *) trans->journal_entries + trans->journal_entries_u64s);
+       for (struct jset_entry *i = btree_trans_journal_entries_start(trans);
+            i != btree_trans_journal_entries_top(trans);
             i = vstruct_next(i)) {
                ret = bch2_journal_entry_validate(c, NULL, i,
                                                  bcachefs_metadata_version_current,
@@ -754,11 +755,11 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
                }
 
                memcpy_u64s_small(journal_res_entry(&c->journal, &trans->journal_res),
-                                 trans->journal_entries,
-                                 trans->journal_entries_u64s);
+                                 btree_trans_journal_entries_start(trans),
+                                 trans->journal_entries.u64s);
 
-               trans->journal_res.offset       += trans->journal_entries_u64s;
-               trans->journal_res.u64s         -= trans->journal_entries_u64s;
+               trans->journal_res.offset       += trans->journal_entries.u64s;
+               trans->journal_res.u64s         -= trans->journal_entries.u64s;
 
                if (trans->journal_seq)
                        *trans->journal_seq = trans->journal_res.seq;
@@ -780,7 +781,7 @@ fatal_err:
        bch2_fs_fatal_error(c, "fatal error in transaction commit: %s", bch2_err_str(ret));
        percpu_down_read(&c->mark_lock);
 revert_fs_usage:
-       for (struct jset_entry *entry2 = trans->journal_entries;
+       for (struct jset_entry *entry2 = btree_trans_journal_entries_start(trans);
             entry2 != entry;
             entry2 = vstruct_next(entry2))
                if (entry2->type == BCH_JSET_ENTRY_write_buffer_keys &&
@@ -961,8 +962,8 @@ do_bch2_trans_commit_to_journal_replay(struct btree_trans *trans)
                        return ret;
        }
 
-       for (struct jset_entry *i = trans->journal_entries;
-            i != (void *) ((u64 *) trans->journal_entries + trans->journal_entries_u64s);
+       for (struct jset_entry *i = btree_trans_journal_entries_start(trans);
+            i != btree_trans_journal_entries_top(trans);
             i = vstruct_next(i))
                if (i->type == BCH_JSET_ENTRY_btree_keys ||
                    i->type == BCH_JSET_ENTRY_write_buffer_keys) {
@@ -987,7 +988,7 @@ int __bch2_trans_commit(struct btree_trans *trans, unsigned flags)
                goto out_reset;
 
        if (!trans->nr_updates &&
-           !trans->journal_entries_u64s)
+           !trans->journal_entries.u64s)
                goto out_reset;
 
        ret = bch2_trans_commit_run_triggers(trans);
@@ -1005,7 +1006,7 @@ int __bch2_trans_commit(struct btree_trans *trans, unsigned flags)
 
        EBUG_ON(test_bit(BCH_FS_clean_shutdown, &c->flags));
 
-       trans->journal_u64s             = trans->journal_entries_u64s;
+       trans->journal_u64s             = trans->journal_entries.u64s;
        trans->journal_transaction_names = READ_ONCE(c->opts.journal_transaction_names);
        if (trans->journal_transaction_names)
                trans->journal_u64s += jset_u64s(JSET_ENTRY_LOG_U64s);
index e5a965db68b47739acc631c3dbcf6899c0b3eb58..7ebf43fc8baebcfd5bd9a063ac0d9acee9231750 100644 (file)
@@ -480,6 +480,12 @@ struct trans_kmalloc_trace {
 };
 typedef DARRAY(struct trans_kmalloc_trace) darray_trans_kmalloc_trace;
 
+struct btree_trans_subbuf {
+       u16                     base;
+       u16                     u64s;
+       u16                     size;;
+};
+
 struct btree_trans {
        struct bch_fs           *c;
 
@@ -534,9 +540,7 @@ struct btree_trans {
        int                     srcu_idx;
 
        /* update path: */
-       u16                     journal_entries_u64s;
-       u16                     journal_entries_size;
-       struct jset_entry       *journal_entries;
+       struct btree_trans_subbuf journal_entries;
 
        struct btree_trans_commit_hook *hooks;
        struct journal_entry_pin *journal_pin;
index ce83cd037551dca0355368aeea241531b8ff45b5..20fba8d17431b3fff87e7437fa0e6d64839581e6 100644 (file)
@@ -565,30 +565,29 @@ int bch2_btree_insert_clone_trans(struct btree_trans *trans,
        return bch2_btree_insert_trans(trans, btree, n, 0);
 }
 
-struct jset_entry *__bch2_trans_jset_entry_alloc(struct btree_trans *trans, unsigned u64s)
+void *__bch2_trans_subbuf_alloc(struct btree_trans *trans,
+                               struct btree_trans_subbuf *buf,
+                               unsigned u64s)
 {
-       unsigned new_top = trans->journal_entries_u64s + u64s;
-       unsigned old_size = trans->journal_entries_size;
+       unsigned new_top = buf->u64s + u64s;
+       unsigned old_size = buf->size;
 
-       if (new_top > trans->journal_entries_size) {
-               trans->journal_entries_size = roundup_pow_of_two(new_top);
+       if (new_top > buf->size)
+               buf->size = roundup_pow_of_two(new_top);
 
-               btree_trans_stats(trans)->journal_entries_size = trans->journal_entries_size;
-       }
-
-       struct jset_entry *n =
-               bch2_trans_kmalloc_nomemzero(trans,
-                               trans->journal_entries_size * sizeof(u64));
+       void *n = bch2_trans_kmalloc_nomemzero(trans, buf->size * sizeof(u64));
        if (IS_ERR(n))
-               return ERR_CAST(n);
+               return n;
 
-       if (trans->journal_entries)
-               memcpy(n, trans->journal_entries, old_size * sizeof(u64));
-       trans->journal_entries = n;
+       if (buf->u64s)
+               memcpy(n,
+                      btree_trans_subbuf_base(trans, buf),
+                      old_size * sizeof(u64));
+       buf->base = (u64 *) n - (u64 *) trans->mem;
 
-       struct jset_entry *e = btree_trans_journal_entries_top(trans);
-       trans->journal_entries_u64s = new_top;
-       return e;
+       void *p = btree_trans_subbuf_top(trans, buf);
+       buf->u64s = new_top;
+       return p;
 }
 
 int bch2_bkey_get_empty_slot(struct btree_trans *trans, struct btree_iter *iter,
index 3a246610b6733b8de0829329b481f8179d5ec3f4..8964b321804ccb21ce1ee8e42a60296d752127fb 100644 (file)
@@ -113,23 +113,49 @@ bch2_trans_update(struct btree_trans *trans, struct btree_iter *iter,
        return bch2_trans_update_ip(trans, iter, k, flags, _THIS_IP_);
 }
 
-struct jset_entry *__bch2_trans_jset_entry_alloc(struct btree_trans *, unsigned);
+static inline void *btree_trans_subbuf_base(struct btree_trans *trans,
+                                           struct btree_trans_subbuf *buf)
+{
+       return (u64 *) trans->mem + buf->base;
+}
+
+static inline void *btree_trans_subbuf_top(struct btree_trans *trans,
+                                          struct btree_trans_subbuf *buf)
+{
+       return (u64 *) trans->mem + buf->base + buf->u64s;
+}
+
+void *__bch2_trans_subbuf_alloc(struct btree_trans *,
+                               struct btree_trans_subbuf *,
+                               unsigned);
+
+static inline void *
+bch2_trans_subbuf_alloc(struct btree_trans *trans,
+                       struct btree_trans_subbuf *buf,
+                       unsigned u64s)
+{
+       if (buf->u64s + u64s > buf->size)
+               return __bch2_trans_subbuf_alloc(trans, buf, u64s);
+
+       void *p = btree_trans_subbuf_top(trans, buf);
+       buf->u64s += u64s;
+       return p;
+}
+
+static inline struct jset_entry *btree_trans_journal_entries_start(struct btree_trans *trans)
+{
+       return btree_trans_subbuf_base(trans, &trans->journal_entries);
+}
 
 static inline struct jset_entry *btree_trans_journal_entries_top(struct btree_trans *trans)
 {
-       return (void *) ((u64 *) trans->journal_entries + trans->journal_entries_u64s);
+       return btree_trans_subbuf_top(trans, &trans->journal_entries);
 }
 
 static inline struct jset_entry *
 bch2_trans_jset_entry_alloc(struct btree_trans *trans, unsigned u64s)
 {
-       if (!trans->journal_entries ||
-           trans->journal_entries_u64s + u64s > trans->journal_entries_size)
-               return __bch2_trans_jset_entry_alloc(trans, u64s);
-
-       struct jset_entry *e = btree_trans_journal_entries_top(trans);
-       trans->journal_entries_u64s += u64s;
-       return e;
+       return bch2_trans_subbuf_alloc(trans, &trans->journal_entries, u64s);
 }
 
 int bch2_btree_insert_clone_trans(struct btree_trans *, enum btree_id, struct bkey_i *);
@@ -227,7 +253,8 @@ static inline void bch2_trans_reset_updates(struct btree_trans *trans)
                bch2_path_put(trans, i->path, true);
 
        trans->nr_updates               = 0;
-       trans->journal_entries_u64s     = 0;
+       trans->journal_entries.u64s     = 0;
+       trans->journal_entries.size     = 0;
        trans->hooks                    = NULL;
        trans->extra_disk_res           = 0;
 }
index a26bc81a8f497e455d4a1ed5cc4498a43ff85384..04e0d2ac27276c9e4c413ff104230abfb387d814 100644 (file)
@@ -307,8 +307,8 @@ static int bch2_accounting_update_sb_one(struct bch_fs *c, struct bpos p)
  */
 int bch2_accounting_update_sb(struct btree_trans *trans)
 {
-       for (struct jset_entry *i = trans->journal_entries;
-            i != (void *) ((u64 *) trans->journal_entries + trans->journal_entries_u64s);
+       for (struct jset_entry *i = btree_trans_journal_entries_start(trans);
+            i != btree_trans_journal_entries_top(trans);
             i = vstruct_next(i))
                if (jset_entry_is_key(i) && i->start->k.type == KEY_TYPE_accounting) {
                        int ret = bch2_accounting_update_sb_one(trans->c, i->start->k.p);
index 54cb8a5b117d0f4064482e4b93bdd855a0c5a387..54fa3e098c30ede4374a57a860661995c911dcb0 100644 (file)
@@ -259,8 +259,8 @@ static inline int bch2_accounting_trans_commit_hook(struct btree_trans *trans,
                                                    struct bkey_i_accounting *a,
                                                    unsigned commit_flags)
 {
-       a->k.bversion = journal_pos_to_bversion(&trans->journal_res,
-                                               (u64 *) a - (u64 *) trans->journal_entries);
+       u64 *base = (u64 *) btree_trans_subbuf_base(trans, &trans->journal_entries);
+       a->k.bversion = journal_pos_to_bversion(&trans->journal_res, (u64 *) a - base);
 
        EBUG_ON(bversion_zero(a->k.bversion));