[PATCH v3 2/3] fs: btrfs: release the path when btrfs_search_slot() fails

Cole Munz <[email protected]> Sun, 02 Aug 2026 09:35:22 +0000
Newsgroups gmane.comp.boot-loaders.u-boot
Message-ID <029949953a54514c74303f9a2211e10b6ccb2f8f.1785660029.git.Munzzyy1@proton.me>
The U-Boot copy of btrfs_search_slot() returns on error with the nodes
it has descended through still attached to the path. The kernel one
releases the path on any error unless p->skip_release_on_error is set,
and callers written against that convention treat a failed search as
owning nothing. btrfs_size() is one: it returns straight away on a
search error and never reaches its btrfs_release_path() call, so the
attached extent buffer references leak.

Route both error exits through a release of the path. The error
returns of read_node_slot() carry no extra reference, so the path is
the only thing to clean up.

Suggested-by: Qu Wenruo <[email protected]>
Signed-off-by: Cole Munz <[email protected]>
---
 fs/btrfs/ctree.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 8e932adc425d..48c50e556b16 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -425,8 +425,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans,
 		level = btrfs_header_level(b);
 		p->nodes[level] = b;
 		ret = check_block(fs_info, p, level);
-		if (ret)
-			return -1;
+		if (ret) {
+			ret = -1;
+			goto err;
+		}
 		ret = btrfs_bin_search(b, key, &slot);
 		if (level != 0) {
 			if (ret && slot > 0)
@@ -461,8 +463,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans,
 				break;
 
 			b = read_node_slot(fs_info, b, slot);
-			if (!extent_buffer_uptodate(b))
-				return -EIO;
+			if (!extent_buffer_uptodate(b)) {
+				ret = -EIO;
+				goto err;
+			}
 		} else {
 			p->slots[level] = slot;
 			/*
@@ -479,6 +483,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans,
 		}
 	}
 	return 1;
+
+err:
+	btrfs_release_path(p);
+	return ret;
 }
 
 /*
-- 
2.55.0