diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2024-02-05 22:30:51 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-02-13 21:59:34 -0500 |
commit | 1dfe3c66dafb2e970bbd8f4e139ef704b89880c4 (patch) | |
tree | 7f5f28aedc857e1b87849d1f7d59f22c5b6514c8 | |
parent | a74a41ae99eaab24b9d0cb6341dc7b2f7a7ef5f8 (diff) |
bcachefs: Check subvol <-> inode pointers in check_inode()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/fsck.c | 25 | ||||
-rw-r--r-- | fs/bcachefs/sb-errors_types.h | 4 |
2 files changed, 28 insertions, 1 deletions
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index a4b44c4f9bdc..e4a8a14c46bc 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -923,6 +923,31 @@ static int check_inode(struct btree_trans *trans, do_update = true; } + if (u.bi_subvol) { + struct bch_subvolume s; + + ret = bch2_subvolume_get(trans, u.bi_subvol, false, 0, &s); + if (ret && !bch2_err_matches(ret, ENOENT)) + goto err; + + if (fsck_err_on(ret, + c, inode_bi_subvol_missing, + "inode %llu:%u bi_subvol points to missing subvolume %u", + u.bi_inum, k.k->p.snapshot, u.bi_subvol) || + fsck_err_on(le64_to_cpu(s.inode) != u.bi_inum || + !bch2_snapshot_is_ancestor(c, le32_to_cpu(s.snapshot), + k.k->p.snapshot), + c, inode_bi_subvol_wrong, + "inode %llu:%u points to subvol %u, but subvol points to %llu:%u", + u.bi_inum, k.k->p.snapshot, u.bi_subvol, + le64_to_cpu(s.inode), + le32_to_cpu(s.snapshot))) { + u.bi_subvol = 0; + u.bi_parent_subvol = 0; + do_update = true; + } + } + if (do_update) { ret = __bch2_fsck_write_inode(trans, &u, iter->pos.snapshot); bch_err_msg(c, ret, "in fsck updating inode"); diff --git a/fs/bcachefs/sb-errors_types.h b/fs/bcachefs/sb-errors_types.h index cadf12ce9173..63f18c7f3088 100644 --- a/fs/bcachefs/sb-errors_types.h +++ b/fs/bcachefs/sb-errors_types.h @@ -251,7 +251,9 @@ x(hash_table_key_wrong_offset, 243) \ x(unlinked_inode_not_on_deleted_list, 244) \ x(reflink_p_front_pad_bad, 245) \ - x(journal_entry_dup_same_device, 246) + x(journal_entry_dup_same_device, 246) \ + x(inode_bi_subvol_missing, 247) \ + x(inode_bi_subvol_wrong, 248) enum bch_sb_error_id { #define x(t, n) BCH_FSCK_ERR_##t = n, |