]> git.dujemihanovic.xyz Git - linux.git/commitdiff
bcachefs: Check for directories with no backpointers
authorKent Overstreet <kent.overstreet@linux.dev>
Sat, 28 Sep 2024 19:27:37 +0000 (15:27 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 5 Oct 2024 00:25:32 +0000 (20:25 -0400)
It's legal for regular files to have missing backpointers (due to
hardlinks), and fsck should automatically add them, but for directories
this is an error that should be flagged.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fsck.c
fs/bcachefs/sb-errors_format.h

index f0d6696c4df6162aeec3d47b8ac01c7aca6af995..d2aa6a5bc973e6ad744647a652a31cc335d1a158 100644 (file)
@@ -1826,6 +1826,21 @@ static int check_dirent_inode_dirent(struct btree_trans *trans,
        if (inode_points_to_dirent(target, d))
                return 0;
 
+       if (!target->bi_dir &&
+           !target->bi_dir_offset) {
+               fsck_err_on(S_ISDIR(target->bi_mode),
+                           trans, inode_dir_missing_backpointer,
+                           "directory with missing backpointer\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));
+
+               target->bi_dir          = d.k->p.inode;
+               target->bi_dir_offset   = d.k->p.offset;
+               return __bch2_fsck_write_inode(trans, target, target_snapshot);
+       }
+
        if (bch2_inode_should_have_bp(target) &&
            !fsck_err(trans, inode_wrong_backpointer,
                      "dirent points to inode that does not point back:\n  %s",
@@ -1835,13 +1850,6 @@ static int check_dirent_inode_dirent(struct btree_trans *trans,
                       buf.buf)))
                goto err;
 
-       if (!target->bi_dir &&
-           !target->bi_dir_offset) {
-               target->bi_dir          = d.k->p.inode;
-               target->bi_dir_offset   = d.k->p.offset;
-               return __bch2_fsck_write_inode(trans, target, target_snapshot);
-       }
-
        struct bkey_s_c_dirent bp_dirent = dirent_get_by_pos(trans, &bp_iter,
                              SPOS(target->bi_dir, target->bi_dir_offset, target_snapshot));
        ret = bkey_err(bp_dirent);
index b4024870b65e88b0faad566df838957622122c62..fc3d31ed5975c8a7ee2d4ef60cb3cff577dac29a 100644 (file)
@@ -219,6 +219,7 @@ enum bch_fsck_flags {
        x(inode_i_sectors_wrong,                                204,    FSCK_AUTOFIX)   \
        x(inode_dir_wrong_nlink,                                205,    FSCK_AUTOFIX)   \
        x(inode_dir_multiple_links,                             206,    FSCK_AUTOFIX)   \
+       x(inode_dir_missing_backpointer,                        284,    FSCK_AUTOFIX)   \
        x(inode_multiple_links_but_nlink_0,                     207,    FSCK_AUTOFIX)   \
        x(inode_wrong_backpointer,                              208,    FSCK_AUTOFIX)   \
        x(inode_wrong_nlink,                                    209,    FSCK_AUTOFIX)   \
@@ -295,7 +296,7 @@ enum bch_fsck_flags {
        x(accounting_key_replicas_devs_unsorted,                280,    FSCK_AUTOFIX)   \
        x(accounting_key_version_0,                             282,    FSCK_AUTOFIX)   \
        x(logged_op_but_clean,                                  283,    FSCK_AUTOFIX)   \
-       x(MAX,                                                  284,    0)
+       x(MAX,                                                  285,    0)
 
 enum bch_sb_error_id {
 #define x(t, n, ...) BCH_FSCK_ERR_##t = n,