diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2024-04-25 22:11:49 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-04-26 02:03:00 -0400 |
commit | db454840a692d5835afa268a0b1981425399bedd (patch) | |
tree | c0dd47da386ca12107bc84690633a4495c99f934 | |
parent | dc6db4dd69aa5af106fc6239529911aea9a936fe (diff) |
bcachefs: check for inodes that should have backpointers in fsck
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/fsck.c | 10 | ||||
-rw-r--r-- | fs/bcachefs/inode.h | 8 |
2 files changed, 18 insertions, 0 deletions
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 4adb96965e11..c8f57465131c 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -1713,6 +1713,15 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, if (inode_points_to_dirent(target, d)) return 0; + if (bch2_inode_should_have_bp(target) && + !fsck_err(c, inode_wrong_backpointer, + "dirent points to inode that does not point back:\n %s", + (bch2_bkey_val_to_text(&buf, c, d.s_c), + prt_printf(&buf, "\n "), + bch2_inode_unpacked_to_text(&buf, target), + buf.buf))) + goto out_noiter; + if (!target->bi_dir && !target->bi_dir_offset) { target->bi_dir = d.k->p.inode; @@ -1781,6 +1790,7 @@ out: err: fsck_err: bch2_trans_iter_exit(trans, &bp_iter); +out_noiter: printbuf_exit(&buf); bch_err_fn(c, ret); return ret; diff --git a/fs/bcachefs/inode.h b/fs/bcachefs/inode.h index 46477a40846c..abdfb1f3e4d0 100644 --- a/fs/bcachefs/inode.h +++ b/fs/bcachefs/inode.h @@ -221,6 +221,14 @@ static inline void bch2_inode_nlink_set(struct bch_inode_unpacked *bi, int bch2_inode_nlink_inc(struct bch_inode_unpacked *); void bch2_inode_nlink_dec(struct btree_trans *, struct bch_inode_unpacked *); +static inline bool bch2_inode_should_have_bp(struct bch_inode_unpacked *inode) +{ + bool inode_has_bp = inode->bi_dir || inode->bi_dir_offset; + + return S_ISDIR(inode->bi_mode) || + (!inode->bi_nlink && inode_has_bp); +} + struct bch_opts bch2_inode_opts_to_opts(struct bch_inode_unpacked *); void bch2_inode_opts_get(struct bch_io_opts *, struct bch_fs *, struct bch_inode_unpacked *); |