[PATCH] btrfs: do not insert dir index if there is a conflicting dir item name

Qu Wenruo <[email protected]>
Newsgroups org.kernel.vger.linux-btrfs
Message-ID <3cc8583892db7e3d03c0e252a31a8b0565ae2d30.1786680299.git.wqu@suse.com>
Inside btrfs_insert_dir_item(), if we hit an -EEXIST error from
insert_with_overflow(), we continue to second_insert label, which will
insert the corresponding dir index.

However insert_with_overflow() does not return -EEXIST just because there
is a hash conflict, but only when there is a completely same name in the
existing dir item.

So when we got -EEXIST insert_with_overflow(), it really means there is
an conflicting name, and we should not continue.

If we continue to the second_insert label, we will create another dir
index for an existing name, which will corrupt the fs.

For the existing callers, the btrfs_add_link() is already properly
handling the -EEXIST error without aborting (unless the inode ref is
unable to be reverted).

The only call site that aborts is from create_pending_snapshot(), but
that's the expected behavior as we have no way to revert the created
subvolume.

This bug is reported by Sashiko while reviewing a patch touching code
around the offending location.
But since it's an existing bug, it's not shown in the summary page.

Link: https://sashiko.dev/#/patchset/20260811-btrfs-enomem-v3-0-46a993fc3fe5%40kernel.org
Fixes: e06afa839e72 ("Btrfs: rename")
Signed-off-by: Qu Wenruo <[email protected]>
---
 fs/btrfs/dir-item.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
index 30ddafaf8d3d..a6bd69be522b 100644
--- a/fs/btrfs/dir-item.c
+++ b/fs/btrfs/dir-item.c
@@ -149,8 +149,6 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans,
 					name->name, name->len);
 	if (IS_ERR(dir_item)) {
 		ret = PTR_ERR(dir_item);
-		if (ret == -EEXIST)
-			goto second_insert;
 		goto out_free_prealloc;
 	}
 
@@ -167,7 +165,6 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans,
 
 	write_extent_buffer(leaf, name->name, name_ptr, name->len);
 
-second_insert:
 	if (!need_delayed_index) {
 		ret = 0;
 		goto out_free_prealloc;
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.