aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorGravatar Kent Overstreet <kent.overstreet@linux.dev> 2023-02-19 00:49:51 -0500
committerGravatar Kent Overstreet <kent.overstreet@linux.dev> 2023-10-22 17:09:54 -0400
commit9f6db1276c0c80b017f9278d6f081f20cecbeb33 (patch)
treed5561e8fa1a054b63b9bd04cb89f315cd4f9fa61 /fs
parentbcachefs: Fix ec repair code check (diff)
downloadlinux-9f6db1276c0c80b017f9278d6f081f20cecbeb33.tar.gz
linux-9f6db1276c0c80b017f9278d6f081f20cecbeb33.tar.bz2
linux-9f6db1276c0c80b017f9278d6f081f20cecbeb33.zip
bcachefs: bch2_journal_entries_postprocess()
This brings back journal_entries_compact(), but in a more efficient form - we need to do multiple postprocess steps, so iterate over the journal entries being written just once to make it more efficient. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/btree_update_interior.c15
-rw-r--r--fs/bcachefs/btree_update_interior.h2
-rw-r--r--fs/bcachefs/journal_io.c48
3 files changed, 53 insertions, 12 deletions
diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c
index 45004f17d51d..ad86c0b9e42e 100644
--- a/fs/bcachefs/btree_update_interior.c
+++ b/fs/bcachefs/btree_update_interior.c
@@ -2402,20 +2402,15 @@ bool bch2_btree_interior_updates_flush(struct bch_fs *c)
return ret;
}
-void bch2_journal_entries_to_btree_roots(struct bch_fs *c, struct jset *jset)
+void bch2_journal_entry_to_btree_root(struct bch_fs *c, struct jset_entry *entry)
{
- struct btree_root *r;
- struct jset_entry *entry;
+ struct btree_root *r = &c->btree_roots[entry->btree_id];
mutex_lock(&c->btree_root_lock);
- vstruct_for_each(jset, entry)
- if (entry->type == BCH_JSET_ENTRY_btree_root) {
- r = &c->btree_roots[entry->btree_id];
- r->level = entry->level;
- r->alive = true;
- bkey_copy(&r->key, &entry->start[0]);
- }
+ r->level = entry->level;
+ r->alive = true;
+ bkey_copy(&r->key, &entry->start[0]);
mutex_unlock(&c->btree_root_lock);
}
diff --git a/fs/bcachefs/btree_update_interior.h b/fs/bcachefs/btree_update_interior.h
index 30e9c137b0e2..dcfd7ceacc59 100644
--- a/fs/bcachefs/btree_update_interior.h
+++ b/fs/bcachefs/btree_update_interior.h
@@ -314,7 +314,7 @@ void bch2_btree_updates_to_text(struct printbuf *, struct bch_fs *);
bool bch2_btree_interior_updates_flush(struct bch_fs *);
-void bch2_journal_entries_to_btree_roots(struct bch_fs *, struct jset *);
+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 *);
diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c
index c6bb78d2a07f..377c07125183 100644
--- a/fs/bcachefs/journal_io.c
+++ b/fs/bcachefs/journal_io.c
@@ -1621,6 +1621,52 @@ static void do_journal_write(struct closure *cl)
return;
}
+static void bch2_journal_entries_postprocess(struct bch_fs *c, struct jset *jset)
+{
+ struct jset_entry *i, *next, *prev = NULL;
+
+ /*
+ * Simple compaction, dropping empty jset_entries (from journal
+ * reservations that weren't fully used) and merging jset_entries that
+ * can be.
+ *
+ * If we wanted to be really fancy here, we could sort all the keys in
+ * the jset and drop keys that were overwritten - probably not worth it:
+ */
+ vstruct_for_each_safe(jset, i, next) {
+ unsigned u64s = le16_to_cpu(i->u64s);
+
+ /* Empty entry: */
+ if (!u64s)
+ continue;
+
+ if (i->type == BCH_JSET_ENTRY_btree_root)
+ bch2_journal_entry_to_btree_root(c, i);
+
+ /* Can we merge with previous entry? */
+ if (prev &&
+ i->btree_id == prev->btree_id &&
+ i->level == prev->level &&
+ i->type == prev->type &&
+ i->type == BCH_JSET_ENTRY_btree_keys &&
+ le16_to_cpu(prev->u64s) + u64s <= U16_MAX) {
+ memmove_u64s_down(vstruct_next(prev),
+ i->_data,
+ u64s);
+ le16_add_cpu(&prev->u64s, u64s);
+ continue;
+ }
+
+ /* Couldn't merge, move i into new position (after prev): */
+ prev = prev ? vstruct_next(prev) : jset->start;
+ if (i != prev)
+ memmove_u64s_down(prev, i, jset_u64s(u64s));
+ }
+
+ prev = prev ? vstruct_next(prev) : jset->start;
+ jset->u64s = cpu_to_le32((u64 *) prev - jset->_data);
+}
+
void bch2_journal_write(struct closure *cl)
{
struct journal *j = container_of(cl, struct journal, io);
@@ -1692,7 +1738,7 @@ void bch2_journal_write(struct closure *cl)
* entry:
*/
- bch2_journal_entries_to_btree_roots(c, jset);
+ bch2_journal_entries_postprocess(c, jset);
start = end = vstruct_last(jset);