bcachefs: Don't iterate over journal entries just for btree roots
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 3 Nov 2023 01:43:26 +0000 (21:43 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 5 Nov 2023 18:12:18 +0000 (13:12 -0500)
Small performance optimization, and a bit of a code cleanup too.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_update_interior.c
fs/bcachefs/btree_update_interior.h
fs/bcachefs/journal_io.c
fs/bcachefs/sb-clean.c

index 89ada89eafe7b79096f806da7541b94939fd2da1..39c2db68123bd1e7958cb69540721a1548d92516 100644 (file)
@@ -2418,23 +2418,17 @@ void bch2_journal_entry_to_btree_root(struct bch_fs *c, struct jset_entry *entry
 
 struct jset_entry *
 bch2_btree_roots_to_journal_entries(struct bch_fs *c,
-                                   struct jset_entry *start,
-                                   struct jset_entry *end)
+                                   struct jset_entry *end,
+                                   unsigned long skip)
 {
-       struct jset_entry *entry;
-       unsigned long have = 0;
        unsigned i;
 
-       for (entry = start; entry < end; entry = vstruct_next(entry))
-               if (entry->type == BCH_JSET_ENTRY_btree_root)
-                       __set_bit(entry->btree_id, &have);
-
        mutex_lock(&c->btree_root_lock);
 
        for (i = 0; i < btree_id_nr_alive(c); i++) {
                struct btree_root *r = bch2_btree_id_root(c, i);
 
-               if (r->alive && !test_bit(i, &have)) {
+               if (r->alive && !test_bit(i, &skip)) {
                        journal_entry_set(end, BCH_JSET_ENTRY_btree_root,
                                          i, r->level, &r->key, r->key.k.u64s);
                        end = vstruct_next(end);
index c2ffeb30884d795ebbdcdc08f7804c1803779352..4df21512d640dac83c8948137dfa4fd077b2ef39 100644 (file)
@@ -325,7 +325,7 @@ bool bch2_btree_interior_updates_flush(struct bch_fs *);
 
 void bch2_journal_entry_to_btree_root(struct bch_fs *, struct jset_entry *);
 struct jset_entry *bch2_btree_roots_to_journal_entries(struct bch_fs *,
-                                       struct jset_entry *, struct jset_entry *);
+                                       struct jset_entry *, unsigned long);
 
 void bch2_do_pending_node_rewrites(struct bch_fs *);
 void bch2_free_pending_node_rewrites(struct bch_fs *);
index 392e90d4d4fbeb2131b5ed3e47e7020af0643bf2..f4bc2cdbfdd7921b4d562cf0df7d29b1f8c51c87 100644 (file)
@@ -1678,9 +1678,15 @@ static void do_journal_write(struct closure *cl)
        continue_at(cl, journal_write_done, c->io_complete_wq);
 }
 
-static void bch2_journal_entries_postprocess(struct bch_fs *c, struct jset *jset)
+static int bch2_journal_write_prep(struct journal *j, struct journal_buf *w)
 {
-       struct jset_entry *i, *next, *prev = NULL;
+       struct bch_fs *c = container_of(j, struct bch_fs, journal);
+       struct jset_entry *start, *end, *i, *next, *prev = NULL;
+       struct jset *jset = w->data;
+       unsigned sectors, bytes, u64s;
+       bool validate_before_checksum = false;
+       unsigned long btree_roots_have = 0;
+       int ret;
 
        /*
         * Simple compaction, dropping empty jset_entries (from journal
@@ -1697,8 +1703,20 @@ static void bch2_journal_entries_postprocess(struct bch_fs *c, struct jset *jset
                if (!u64s)
                        continue;
 
-               if (i->type == BCH_JSET_ENTRY_btree_root)
+               /*
+                * New btree roots are set by journalling them; when the journal
+                * entry gets written we have to propagate them to
+                * c->btree_roots
+                *
+                * But, every journal entry we write has to contain all the
+                * btree roots (at least for now); so after we copy btree roots
+                * to c->btree_roots we have to get any missing btree roots and
+                * add them to this journal entry:
+                */
+               if (i->type == BCH_JSET_ENTRY_btree_root) {
                        bch2_journal_entry_to_btree_root(c, i);
+                       __set_bit(i->btree_id, &btree_roots_have);
+               }
 
                /* Can we merge with previous entry? */
                if (prev &&
@@ -1722,35 +1740,10 @@ static void bch2_journal_entries_postprocess(struct bch_fs *c, struct jset *jset
 
        prev = prev ? vstruct_next(prev) : jset->start;
        jset->u64s = cpu_to_le32((u64 *) prev - jset->_data);
-}
-
-static int bch2_journal_write_prep(struct journal *j, struct journal_buf *w)
-{
-       struct bch_fs *c = container_of(j, struct bch_fs, journal);
-       struct jset_entry *start, *end;
-       struct jset *jset;
-       unsigned sectors, bytes, u64s;
-       bool validate_before_checksum = false;
-       int ret;
-
-       journal_buf_realloc(j, w);
-       jset = w->data;
-
-       /*
-        * New btree roots are set by journalling them; when the journal entry
-        * gets written we have to propagate them to c->btree_roots
-        *
-        * But, every journal entry we write has to contain all the btree roots
-        * (at least for now); so after we copy btree roots to c->btree_roots we
-        * have to get any missing btree roots and add them to this journal
-        * entry:
-        */
-
-       bch2_journal_entries_postprocess(c, jset);
 
        start = end = vstruct_last(jset);
 
-       end     = bch2_btree_roots_to_journal_entries(c, jset->start, end);
+       end     = bch2_btree_roots_to_journal_entries(c, end, btree_roots_have);
 
        bch2_journal_super_entries_add_common(c, &end,
                                le64_to_cpu(jset->seq));
@@ -1872,6 +1865,8 @@ void bch2_journal_write(struct closure *cl)
        if (ret)
                goto err;
 
+       journal_buf_realloc(j, w);
+
        ret = bch2_journal_write_prep(j, w);
        if (ret)
                goto err;
index 9b6cc86d264a1f9e2412a552a0547c6d3f4d4f28..e151ada1c8bd2db23e31bc1f6f027815585e8ab2 100644 (file)
@@ -376,7 +376,7 @@ void bch2_fs_mark_clean(struct bch_fs *c)
 
        entry = sb_clean->start;
        bch2_journal_super_entries_add_common(c, &entry, 0);
-       entry = bch2_btree_roots_to_journal_entries(c, entry, entry);
+       entry = bch2_btree_roots_to_journal_entries(c, entry, 0);
        BUG_ON((void *) entry > vstruct_end(&sb_clean->field));
 
        memset(entry, 0,