bcachefs: check for inodes that should have backpointers in fsck
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 26 Apr 2024 02:11:49 +0000 (22:11 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 8 May 2024 21:29:21 +0000 (17:29 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fsck.c
fs/bcachefs/inode.h

index 4adb96965e111a30412e8124dbdba5da83b08003..c8f57465131c54becd0cb745d7ce2b54b1e87cd1 100644 (file)
@@ -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;
index 46477a40846c430f590886089de06dcb2ad0256c..abdfb1f3e4d08f1ef7b6ca6e952aabcc032496d8 100644 (file)
@@ -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 *);