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>
This commit is contained in:
parent
7546c78df1
commit
9f6db1276c
@ -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);
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user