Skip to content

Commit 15734b5

Browse files
author
Kent Overstreet
committed
bcachefs: Check for dirents to overwritten inodes
This fixes various "dirent to missing inode" errors. Signed-off-by: Kent Overstreet <[email protected]>
1 parent d3d0fac commit 15734b5

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

fs/bcachefs/fsck.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -832,11 +832,13 @@ struct inode_walker {
832832
struct bpos last_pos;
833833

834834
DARRAY(struct inode_walker_entry) inodes;
835+
snapshot_id_list deletes;
835836
};
836837

837838
static void inode_walker_exit(struct inode_walker *w)
838839
{
839840
darray_exit(&w->inodes);
841+
darray_exit(&w->deletes);
840842
}
841843

842844
static struct inode_walker inode_walker_init(void)
@@ -960,19 +962,23 @@ static int get_visible_inodes(struct btree_trans *trans,
960962
int ret;
961963

962964
w->inodes.nr = 0;
965+
w->deletes.nr = 0;
963966

964-
for_each_btree_key_norestart(trans, iter, BTREE_ID_inodes, POS(0, inum),
967+
for_each_btree_key_reverse_norestart(trans, iter, BTREE_ID_inodes, SPOS(0, inum, s->pos.snapshot),
965968
BTREE_ITER_all_snapshots, k, ret) {
966969
if (k.k->p.offset != inum)
967970
break;
968971

969972
if (!ref_visible(c, s, s->pos.snapshot, k.k->p.snapshot))
970973
continue;
971974

972-
if (bkey_is_inode(k.k))
973-
add_inode(c, w, k);
975+
if (snapshot_list_has_ancestor(c, &w->deletes, k.k->p.snapshot))
976+
continue;
974977

975-
if (k.k->p.snapshot >= s->pos.snapshot)
978+
ret = bkey_is_inode(k.k)
979+
? add_inode(c, w, k)
980+
: snapshot_list_add(c, &w->deletes, k.k->p.snapshot);
981+
if (ret)
976982
break;
977983
}
978984
bch2_trans_iter_exit(trans, &iter);
@@ -2380,6 +2386,30 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
23802386
if (ret)
23812387
goto err;
23822388
}
2389+
2390+
darray_for_each(target->deletes, i)
2391+
if (fsck_err_on(!snapshot_list_has_id(&s->ids, *i),
2392+
trans, dirent_to_overwritten_inode,
2393+
"dirent points to inode overwritten in snapshot %u:\n%s",
2394+
*i,
2395+
(printbuf_reset(&buf),
2396+
bch2_bkey_val_to_text(&buf, c, k),
2397+
buf.buf))) {
2398+
struct btree_iter delete_iter;
2399+
bch2_trans_iter_init(trans, &delete_iter,
2400+
BTREE_ID_dirents,
2401+
SPOS(k.k->p.inode, k.k->p.offset, *i),
2402+
BTREE_ITER_intent);
2403+
ret = bch2_btree_iter_traverse(&delete_iter) ?:
2404+
bch2_hash_delete_at(trans, bch2_dirent_hash_desc,
2405+
hash_info,
2406+
&delete_iter,
2407+
BTREE_UPDATE_internal_snapshot_node);
2408+
bch2_trans_iter_exit(trans, &delete_iter);
2409+
if (ret)
2410+
goto err;
2411+
2412+
}
23832413
}
23842414

23852415
ret = bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc);

fs/bcachefs/sb-errors_format.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ enum bch_fsck_flags {
256256
x(dirent_in_missing_dir_inode, 227, 0) \
257257
x(dirent_in_non_dir_inode, 228, 0) \
258258
x(dirent_to_missing_inode, 229, 0) \
259+
x(dirent_to_overwritten_inode, 302, 0) \
259260
x(dirent_to_missing_subvol, 230, 0) \
260261
x(dirent_to_itself, 231, 0) \
261262
x(quota_type_invalid, 232, 0) \
@@ -312,7 +313,7 @@ enum bch_fsck_flags {
312313
x(logged_op_but_clean, 283, FSCK_AUTOFIX) \
313314
x(compression_opt_not_marked_in_sb, 295, FSCK_AUTOFIX) \
314315
x(compression_type_not_marked_in_sb, 296, FSCK_AUTOFIX) \
315-
x(MAX, 302, 0)
316+
x(MAX, 303, 0)
316317

317318
enum bch_sb_error_id {
318319
#define x(t, n, ...) BCH_FSCK_ERR_##t = n,

0 commit comments

Comments
 (0)