Commit 1c6051bb authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: Check for directories with no backpointers

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: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 260af156
...@@ -1826,22 +1826,30 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, ...@@ -1826,22 +1826,30 @@ static int check_dirent_inode_dirent(struct btree_trans *trans,
if (inode_points_to_dirent(target, d)) if (inode_points_to_dirent(target, d))
return 0; return 0;
if (bch2_inode_should_have_bp(target) && if (!target->bi_dir &&
!fsck_err(trans, inode_wrong_backpointer, !target->bi_dir_offset) {
"dirent points to inode that does not point back:\n %s", 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), (bch2_bkey_val_to_text(&buf, c, d.s_c),
prt_printf(&buf, "\n "), prt_printf(&buf, "\n "),
bch2_inode_unpacked_to_text(&buf, target), bch2_inode_unpacked_to_text(&buf, target),
buf.buf))) buf.buf));
goto err;
if (!target->bi_dir &&
!target->bi_dir_offset) {
target->bi_dir = d.k->p.inode; target->bi_dir = d.k->p.inode;
target->bi_dir_offset = d.k->p.offset; target->bi_dir_offset = d.k->p.offset;
return __bch2_fsck_write_inode(trans, target, target_snapshot); 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",
(bch2_bkey_val_to_text(&buf, c, d.s_c),
prt_printf(&buf, "\n "),
bch2_inode_unpacked_to_text(&buf, target),
buf.buf)))
goto err;
struct bkey_s_c_dirent bp_dirent = dirent_get_by_pos(trans, &bp_iter, struct bkey_s_c_dirent bp_dirent = dirent_get_by_pos(trans, &bp_iter,
SPOS(target->bi_dir, target->bi_dir_offset, target_snapshot)); SPOS(target->bi_dir, target->bi_dir_offset, target_snapshot));
ret = bkey_err(bp_dirent); ret = bkey_err(bp_dirent);
......
...@@ -219,6 +219,7 @@ enum bch_fsck_flags { ...@@ -219,6 +219,7 @@ enum bch_fsck_flags {
x(inode_i_sectors_wrong, 204, FSCK_AUTOFIX) \ x(inode_i_sectors_wrong, 204, FSCK_AUTOFIX) \
x(inode_dir_wrong_nlink, 205, FSCK_AUTOFIX) \ x(inode_dir_wrong_nlink, 205, FSCK_AUTOFIX) \
x(inode_dir_multiple_links, 206, 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_multiple_links_but_nlink_0, 207, FSCK_AUTOFIX) \
x(inode_wrong_backpointer, 208, FSCK_AUTOFIX) \ x(inode_wrong_backpointer, 208, FSCK_AUTOFIX) \
x(inode_wrong_nlink, 209, FSCK_AUTOFIX) \ x(inode_wrong_nlink, 209, FSCK_AUTOFIX) \
...@@ -295,7 +296,7 @@ enum bch_fsck_flags { ...@@ -295,7 +296,7 @@ enum bch_fsck_flags {
x(accounting_key_replicas_devs_unsorted, 280, FSCK_AUTOFIX) \ x(accounting_key_replicas_devs_unsorted, 280, FSCK_AUTOFIX) \
x(accounting_key_version_0, 282, FSCK_AUTOFIX) \ x(accounting_key_version_0, 282, FSCK_AUTOFIX) \
x(logged_op_but_clean, 283, FSCK_AUTOFIX) \ x(logged_op_but_clean, 283, FSCK_AUTOFIX) \
x(MAX, 284, 0) x(MAX, 285, 0)
enum bch_sb_error_id { enum bch_sb_error_id {
#define x(t, n, ...) BCH_FSCK_ERR_##t = n, #define x(t, n, ...) BCH_FSCK_ERR_##t = n,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment