summaryrefslogtreecommitdiff
path: root/fs/bcachefs/fsck.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-09-29 23:38:37 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2024-10-04 20:25:32 -0400
commitc9306a91c3fdc9915f5408561ea432c70b03383b (patch)
tree6f44794e626f869f83b53ed4616d8092b3ef89e4 /fs/bcachefs/fsck.c
parentc7da5ee2e5cc30faca49e3ea9dbecf8f6ee4f1ea (diff)
downloadlwn-c9306a91c3fdc9915f5408561ea432c70b03383b.tar.gz
lwn-c9306a91c3fdc9915f5408561ea432c70b03383b.zip
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: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/fsck.c')
-rw-r--r--fs/bcachefs/fsck.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
index 09f890539ded..30eca76554f6 100644
--- a/fs/bcachefs/fsck.c
+++ b/fs/bcachefs/fsck.c
@@ -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;