Commit c9306a91 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Check for unlinked, non-empty dirs in check_inode()



We want to check for this early so it can be reattached if necessary in
check_unreachable_inodes(); better than letting it be deleted and having
the children reattached, losing their filenames.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent c7da5ee2
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -1083,6 +1083,23 @@ static int check_inode(struct btree_trans *trans,
		do_update = true;
	}

	if (S_ISDIR(u.bi_mode) && (u.bi_flags & BCH_INODE_unlinked)) {
		/* Check for this early so that check_unreachable_inode() will reattach it */

		ret = bch2_empty_dir_snapshot(trans, k.k->p.offset, 0, k.k->p.snapshot);
		if (ret && ret != -BCH_ERR_ENOTEMPTY_dir_not_empty)
			goto err;

		fsck_err_on(ret, trans, inode_dir_unlinked_but_not_empty,
			    "dir unlinked but not empty\n%s",
			    (printbuf_reset(&buf),
			     bch2_inode_unpacked_to_text(&buf, &u),
			     buf.buf));
		u.bi_flags &= ~BCH_INODE_unlinked;
		do_update = true;
		ret = 0;
	}

	if ((u.bi_flags & (BCH_INODE_i_size_dirty|BCH_INODE_unlinked)) &&
	    bch2_key_has_snapshot_overwrites(trans, BTREE_ID_inodes, k.k->p)) {
		struct bpos new_min_pos;
+2 −1
Original line number Diff line number Diff line
@@ -221,6 +221,7 @@ enum bch_fsck_flags {
	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_dir_unlinked_but_not_empty,			286,	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)	\
@@ -297,7 +298,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,							286,	0)
	x(MAX,							287,	0)

enum bch_sb_error_id {
#define x(t, n, ...) BCH_FSCK_ERR_##t = n,