summaryrefslogtreecommitdiff
path: root/fs/bcachefs/fsck.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-07-16 21:55:33 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:10:07 +0300
commita0076086da73297228665957c3b3bfac2492d67d (patch)
tree84232900739bec99a44febc8eb9ad47fec4eb571 /fs/bcachefs/fsck.c
parent650eb16b45183c7ea7c17e56ac862dc1ad1ec849 (diff)
downloadlinux-a0076086da73297228665957c3b3bfac2492d67d.tar.xz
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: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/fsck.c')
-rw-r--r--fs/bcachefs/fsck.c47
1 files changed, 12 insertions, 35 deletions
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
index 3a3d89bdf1c9..784e55166df2 100644
--- a/fs/bcachefs/fsck.c
+++ b/fs/bcachefs/fsck.c
@@ -471,28 +471,6 @@ static inline void snapshots_seen_init(struct snapshots_seen *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,
enum btree_id btree_id, struct bpos pos)
{
@@ -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
- * that we emit the fewest number of whiteouts necessary:
+ * Check inodes in reverse order, from oldest snapshots to newest,
+ * 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;
--i) {
if (i->snapshot > equiv.snapshot ||
@@ -1419,20 +1401,15 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
if (ret)
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;
}
+
+ if (bkey_extent_is_allocation(k.k))
+ i->count += k.k->size;
}
- }
- if (bkey_extent_is_allocation(k.k))
- for_each_visible_inode(c, s, inode, equiv.snapshot, i)
- i->count += k.k->size;
+ i->seen_this_pos = true;
+ }
out:
err:
fsck_err: