summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/dirent.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-12-07 12:39:13 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-12-08 00:39:56 -0500
commit6d1980f0af439b5fd49b1bee2220deff6888792e (patch)
treebd2d9116e3fabb7ce0f6ad0720384f414857a40c /fs/bcachefs/dirent.c
parente59728883943c6820a0aa413db66a38f2e8c27bd (diff)
downloadlinux-6d1980f0af439b5fd49b1bee2220deff6888792e.tar.gz
linux-6d1980f0af439b5fd49b1bee2220deff6888792e.tar.bz2
linux-6d1980f0af439b5fd49b1bee2220deff6888792e.zip
bcachefs: Fix deleted inode check for dirs
We could delete directories transactionally on rmdir()/unlink(), but we don't; instead, like with regular files we wait for the VFS to call evict(). That means that our check for directories in the deleted inodes btree is wrong - the check should be for non-empty directories. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/dirent.c')
-rw-r--r--fs/bcachefs/dirent.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/fs/bcachefs/dirent.c b/fs/bcachefs/dirent.c
index 1a0f2d571569..2bfff0da7000 100644
--- a/fs/bcachefs/dirent.c
+++ b/fs/bcachefs/dirent.c
@@ -485,20 +485,15 @@ retry:
return ret;
}
-int bch2_empty_dir_trans(struct btree_trans *trans, subvol_inum dir)
+int bch2_empty_dir_snapshot(struct btree_trans *trans, u64 dir, u32 snapshot)
{
struct btree_iter iter;
struct bkey_s_c k;
- u32 snapshot;
int ret;
- ret = bch2_subvolume_get_snapshot(trans, dir.subvol, &snapshot);
- if (ret)
- return ret;
-
for_each_btree_key_upto_norestart(trans, iter, BTREE_ID_dirents,
- SPOS(dir.inum, 0, snapshot),
- POS(dir.inum, U64_MAX), 0, k, ret)
+ SPOS(dir, 0, snapshot),
+ POS(dir, U64_MAX), 0, k, ret)
if (k.k->type == KEY_TYPE_dirent) {
ret = -ENOTEMPTY;
break;
@@ -508,6 +503,14 @@ int bch2_empty_dir_trans(struct btree_trans *trans, subvol_inum dir)
return ret;
}
+int bch2_empty_dir_trans(struct btree_trans *trans, subvol_inum dir)
+{
+ u32 snapshot;
+
+ return bch2_subvolume_get_snapshot(trans, dir.subvol, &snapshot) ?:
+ bch2_empty_dir_snapshot(trans, dir.inum, snapshot);
+}
+
int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
{
struct btree_trans *trans = bch2_trans_get(c);