diff options
| author | Cole Munz <[email protected]> | 2026-08-02 09:35:22 +0000 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-08-10 12:38:57 -0600 |
| commit | 1a5c8af2d4e4b4029739eb8787ce259d74977dfd (patch) | |
| tree | 6491cc1314a081164bad9dcdf1bf1d406b466b3a | |
| parent | 1cf825afd0d7ebb4857002833658574efbef6626 (diff) | |
fs: btrfs: release the path when btrfs_search_slot() fails
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]>
Reviewed-by: Qu Wenruo <[email protected]>
| -rw-r--r-- | fs/btrfs/ctree.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 8e932adc425..48c50e556b1 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; } /* |
