summaryrefslogtreecommitdiff
path: root/fs/bcachefs/fsck.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-07-16 14:24:36 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:10:07 -0400
commitf9f52bc4f0342ddc68690ebdc581eedfbd4a9c6b (patch)
treef796ed308a0e4a888610f7203db6b0e7f0fd50db /fs/bcachefs/fsck.c
parent5897505e67f542452b4f26b6eba949c71e3da7d5 (diff)
bcachefs: fsck: inode_walker: last_pos, seen_this_pos
Prep work for changing check_extent() to avoid key_visible_in_snapshot() - this adds the state to track whether an inode has seen an extent at this pos. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/fsck.c')
-rw-r--r--fs/bcachefs/fsck.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
index f0a760a1701d..45e5a52a106d 100644
--- a/fs/bcachefs/fsck.c
+++ b/fs/bcachefs/fsck.c
@@ -606,12 +606,13 @@ static int ref_visible2(struct bch_fs *c,
struct inode_walker_entry {
struct bch_inode_unpacked inode;
u32 snapshot;
+ bool seen_this_pos;
u64 count;
};
struct inode_walker {
bool first_this_inode;
- u64 cur_inum;
+ struct bpos last_pos;
DARRAY(struct inode_walker_entry) inodes;
};
@@ -648,9 +649,6 @@ static int get_inodes_all_snapshots(struct btree_trans *trans,
u32 restart_count = trans->restart_count;
int ret;
- if (w->cur_inum == inum)
- return 0;
-
w->inodes.nr = 0;
for_each_btree_key(trans, iter, BTREE_ID_inodes, POS(0, inum),
@@ -666,8 +664,7 @@ static int get_inodes_all_snapshots(struct btree_trans *trans,
if (ret)
return ret;
- w->cur_inum = inum;
- w->first_this_inode = true;
+ w->first_this_inode = true;
if (trans_was_restarted(trans, restart_count))
return -BCH_ERR_transaction_restart_nested;
@@ -699,7 +696,7 @@ found:
new.count = 0;
bch_info(c, "have key for inode %llu:%u but have inode in ancestor snapshot %u",
- w->cur_inum, snapshot, i->snapshot);
+ w->last_pos.inode, snapshot, i->snapshot);
while (i > w->inodes.data && i[-1].snapshot > snapshot)
--i;
@@ -715,9 +712,19 @@ found:
static struct inode_walker_entry *walk_inode(struct btree_trans *trans,
struct inode_walker *w, struct bpos pos)
{
- int ret = get_inodes_all_snapshots(trans, w, pos.inode);
- if (ret)
- return ERR_PTR(ret);
+ if (w->last_pos.inode != pos.inode) {
+ int ret = get_inodes_all_snapshots(trans, w, pos.inode);
+ if (ret)
+ return ERR_PTR(ret);
+ } else if (bkey_cmp(w->last_pos, pos)) {
+ struct inode_walker_entry *i;
+
+ darray_for_each(w->inodes, i)
+ i->seen_this_pos = false;
+
+ }
+
+ w->last_pos = pos;
return lookup_inode_for_snapshot(trans->c, w, pos.snapshot);
}
@@ -1128,7 +1135,7 @@ static int check_i_sectors(struct btree_trans *trans, struct inode_walker *w)
if (i->inode.bi_sectors == i->count)
continue;
- count2 = bch2_count_inode_sectors(trans, w->cur_inum, i->snapshot);
+ count2 = bch2_count_inode_sectors(trans, w->last_pos.inode, i->snapshot);
if (i->count != count2) {
bch_err(c, "fsck counted i_sectors wrong: got %llu should be %llu",
@@ -1140,7 +1147,7 @@ static int check_i_sectors(struct btree_trans *trans, struct inode_walker *w)
if (fsck_err_on(!(i->inode.bi_flags & BCH_INODE_I_SECTORS_DIRTY), c,
"inode %llu:%u has incorrect i_sectors: got %llu, should be %llu",
- w->cur_inum, i->snapshot,
+ w->last_pos.inode, i->snapshot,
i->inode.bi_sectors, i->count)) {
i->inode.bi_sectors = i->count;
ret = write_inode(trans, &i->inode, i->snapshot);
@@ -1302,7 +1309,7 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
if (k.k->type == KEY_TYPE_whiteout)
goto out;
- if (inode->cur_inum != k.k->p.inode) {
+ if (inode->last_pos.inode != k.k->p.inode) {
ret = check_i_sectors(trans, inode);
if (ret)
goto err;
@@ -1453,7 +1460,7 @@ static int check_subdir_count(struct btree_trans *trans, struct inode_walker *w)
if (i->inode.bi_nlink == i->count)
continue;
- count2 = bch2_count_subdirs(trans, w->cur_inum, i->snapshot);
+ count2 = bch2_count_subdirs(trans, w->last_pos.inode, i->snapshot);
if (count2 < 0)
return count2;
@@ -1467,7 +1474,7 @@ static int check_subdir_count(struct btree_trans *trans, struct inode_walker *w)
if (fsck_err_on(i->inode.bi_nlink != i->count, c,
"directory %llu:%u with wrong i_nlink: got %u, should be %llu",
- w->cur_inum, i->snapshot, i->inode.bi_nlink, i->count)) {
+ w->last_pos.inode, i->snapshot, i->inode.bi_nlink, i->count)) {
i->inode.bi_nlink = i->count;
ret = write_inode(trans, &i->inode, i->snapshot);
if (ret)
@@ -1631,7 +1638,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
if (k.k->type == KEY_TYPE_whiteout)
goto out;
- if (dir->cur_inum != k.k->p.inode) {
+ if (dir->last_pos.inode != k.k->p.inode) {
ret = check_subdir_count(trans, dir);
if (ret)
goto err;