Commit 769b3600 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Don't iterate over journal entries just for btree roots



Small performance optimization, and a bit of a code cleanup too.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 80396a47
Loading
Loading
Loading
Loading
+3 −9
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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 *);
+24 −29
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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,