Commit e539ebb8 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: simplify check_dirent_inode_dirent()

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 0b498a5a
...@@ -1570,77 +1570,75 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, ...@@ -1570,77 +1570,75 @@ static int check_dirent_inode_dirent(struct btree_trans *trans,
u32 target_snapshot) u32 target_snapshot)
{ {
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
struct btree_iter bp_iter = { NULL };
struct printbuf buf = PRINTBUF; struct printbuf buf = PRINTBUF;
int ret = 0; int ret = 0;
if (inode_points_to_dirent(target, d))
return 0;
if (!target->bi_dir && if (!target->bi_dir &&
!target->bi_dir_offset) { !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);
ret = __bch2_fsck_write_inode(trans, target, target_snapshot);
if (ret)
goto err;
} }
if (!inode_points_to_dirent(target, d)) { struct btree_iter bp_iter = { NULL };
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);
if (ret && !bch2_err_matches(ret, ENOENT)) if (ret && !bch2_err_matches(ret, ENOENT))
goto err; goto err;
bool backpointer_exists = !ret;
ret = 0;
bch2_bkey_val_to_text(&buf, c, d.s_c); bool backpointer_exists = !ret;
prt_newline(&buf); ret = 0;
if (backpointer_exists)
bch2_bkey_val_to_text(&buf, c, bp_dirent.s_c);
if (fsck_err_on(S_ISDIR(target->bi_mode) && backpointer_exists, if (fsck_err_on(!backpointer_exists,
c, inode_dir_multiple_links, c, inode_wrong_backpointer,
"directory %llu:%u with multiple links\n%s", "inode %llu:%u has wrong backpointer:\n"
target->bi_inum, target_snapshot, buf.buf)) { "got %llu:%llu\n"
ret = __remove_dirent(trans, d.k->p); "should be %llu:%llu",
goto out; target->bi_inum, target_snapshot,
} target->bi_dir,
target->bi_dir_offset,
d.k->p.inode,
d.k->p.offset)) {
target->bi_dir = d.k->p.inode;
target->bi_dir_offset = d.k->p.offset;
ret = __bch2_fsck_write_inode(trans, target, target_snapshot);
goto out;
}
/* bch2_bkey_val_to_text(&buf, c, d.s_c);
* hardlinked file with nlink 0: prt_newline(&buf);
* We're just adjusting nlink here so check_nlinks() will pick if (backpointer_exists)
* it up, it ignores inodes with nlink 0 bch2_bkey_val_to_text(&buf, c, bp_dirent.s_c);
*/
if (fsck_err_on(backpointer_exists && !target->bi_nlink, if (fsck_err_on(backpointer_exists &&
c, inode_multiple_links_but_nlink_0, (S_ISDIR(target->bi_mode) ||
"inode %llu:%u type %s has multiple links but i_nlink 0\n%s", target->bi_subvol),
target->bi_inum, target_snapshot, bch2_d_types[d.v->d_type], buf.buf)) { c, inode_dir_multiple_links,
target->bi_nlink++; "%s %llu:%u with multiple links\n%s",
target->bi_flags &= ~BCH_INODE_unlinked; S_ISDIR(target->bi_mode) ? "directory" : "subvolume",
target->bi_inum, target_snapshot, buf.buf)) {
ret = __bch2_fsck_write_inode(trans, target, target_snapshot); ret = __remove_dirent(trans, d.k->p);
if (ret) goto out;
goto err; }
}
if (fsck_err_on(!backpointer_exists, /*
c, inode_wrong_backpointer, * hardlinked file with nlink 0:
"inode %llu:%u has wrong backpointer:\n" * We're just adjusting nlink here so check_nlinks() will pick
"got %llu:%llu\n" * it up, it ignores inodes with nlink 0
"should be %llu:%llu", */
target->bi_inum, target_snapshot, if (fsck_err_on(backpointer_exists && !target->bi_nlink,
target->bi_dir, c, inode_multiple_links_but_nlink_0,
target->bi_dir_offset, "inode %llu:%u type %s has multiple links but i_nlink 0\n%s",
d.k->p.inode, target->bi_inum, target_snapshot, bch2_d_types[d.v->d_type], buf.buf)) {
d.k->p.offset)) { target->bi_nlink++;
target->bi_dir = d.k->p.inode; target->bi_flags &= ~BCH_INODE_unlinked;
target->bi_dir_offset = d.k->p.offset; ret = __bch2_fsck_write_inode(trans, target, target_snapshot);
if (ret)
ret = __bch2_fsck_write_inode(trans, target, target_snapshot); goto err;
if (ret)
goto err;
}
} }
out: out:
err: err:
......
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