Commit a0076086 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: check_extent(): don't use key_visible_in_snapshot()

This changes the main part of check_extents(), that checks the extent
against the corresponding inode, to not use key_visible_in_snapshot().

key_visible_in_snapshot() has to iterate over the list of ancestor
overwrites repeatedly calling bch2_snapshot_is_ancestor(), so this is a
significant performance improvement.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 650eb16b
...@@ -471,28 +471,6 @@ static inline void snapshots_seen_init(struct snapshots_seen *s) ...@@ -471,28 +471,6 @@ static inline void snapshots_seen_init(struct snapshots_seen *s)
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
} }
static int snapshots_seen_add(struct bch_fs *c, struct snapshots_seen *s, u32 id)
{
struct snapshots_seen_entry *i, n = { id, id };
int ret;
darray_for_each(s->ids, i) {
if (n.equiv < i->equiv)
break;
if (i->equiv == n.equiv) {
bch_err(c, "%s(): adding duplicate snapshot", __func__);
return -EINVAL;
}
}
ret = darray_insert_item(&s->ids, i - s->ids.data, n);
if (ret)
bch_err(c, "error reallocating snapshots_seen table (size %zu)",
s->ids.size);
return ret;
}
static int snapshots_seen_update(struct bch_fs *c, struct snapshots_seen *s, static int snapshots_seen_update(struct bch_fs *c, struct snapshots_seen *s,
enum btree_id btree_id, struct bpos pos) enum btree_id btree_id, struct bpos pos)
{ {
...@@ -1391,10 +1369,14 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter, ...@@ -1391,10 +1369,14 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
} }
/* /*
* Check inodes in reverse order, from oldest snapshots to newest, so * Check inodes in reverse order, from oldest snapshots to newest,
* that we emit the fewest number of whiteouts necessary: * starting from the inode that matches this extent's snapshot. If we
* didn't have one, iterate over all inodes:
*/ */
for (i = inode->inodes.data + inode->inodes.nr - 1; if (!i)
i = inode->inodes.data + inode->inodes.nr - 1;
for (;
inode->inodes.data && i >= inode->inodes.data; inode->inodes.data && i >= inode->inodes.data;
--i) { --i) {
if (i->snapshot > equiv.snapshot || if (i->snapshot > equiv.snapshot ||
...@@ -1419,20 +1401,15 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter, ...@@ -1419,20 +1401,15 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
if (ret) if (ret)
goto err; goto err;
if (i->snapshot != equiv.snapshot) {
ret = snapshots_seen_add(c, s, i->snapshot);
if (ret)
goto err;
}
iter->k.type = KEY_TYPE_whiteout; iter->k.type = KEY_TYPE_whiteout;
} }
if (bkey_extent_is_allocation(k.k))
i->count += k.k->size;
} }
}
if (bkey_extent_is_allocation(k.k)) i->seen_this_pos = true;
for_each_visible_inode(c, s, inode, equiv.snapshot, i) }
i->count += k.k->size;
out: out:
err: err:
fsck_err: fsck_err:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment