btrfs: fix leak of path in btrfs_find_item
If btrfs_find_item is called with NULL path it allocates one locally but
does not free it. Affected paths are inserting an orphan item for a file
and for a subvol root.
Move the path allocation to the callers.
CC: <stable@vger.kernel.org> # 3.14+
Fixes: 3f870c2899
("btrfs: expand btrfs_find_item() to include find_orphan_item functionality")
Signed-off-by: David Sterba <dsterba@suse.cz>
This commit is contained in:
parent
eaa27f34e9
commit
381cf6587f
|
@ -2609,32 +2609,23 @@ static int key_search(struct extent_buffer *b, struct btrfs_key *key,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path,
|
||||
int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *path,
|
||||
u64 iobjectid, u64 ioff, u8 key_type,
|
||||
struct btrfs_key *found_key)
|
||||
{
|
||||
int ret;
|
||||
struct btrfs_key key;
|
||||
struct extent_buffer *eb;
|
||||
struct btrfs_path *path;
|
||||
|
||||
ASSERT(path);
|
||||
|
||||
key.type = key_type;
|
||||
key.objectid = iobjectid;
|
||||
key.offset = ioff;
|
||||
|
||||
if (found_path == NULL) {
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
} else
|
||||
path = found_path;
|
||||
|
||||
ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
|
||||
if ((ret < 0) || (found_key == NULL)) {
|
||||
if (path != found_path)
|
||||
btrfs_free_path(path);
|
||||
if ((ret < 0) || (found_key == NULL))
|
||||
return ret;
|
||||
}
|
||||
|
||||
eb = path->nodes[0];
|
||||
if (ret && path->slots[0] >= btrfs_header_nritems(eb)) {
|
||||
|
|
|
@ -1630,6 +1630,7 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
|
|||
bool check_ref)
|
||||
{
|
||||
struct btrfs_root *root;
|
||||
struct btrfs_path *path;
|
||||
int ret;
|
||||
|
||||
if (location->objectid == BTRFS_ROOT_TREE_OBJECTID)
|
||||
|
@ -1669,8 +1670,14 @@ again:
|
|||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = btrfs_find_item(fs_info->tree_root, NULL, BTRFS_ORPHAN_OBJECTID,
|
||||
path = btrfs_alloc_path();
|
||||
if (!path) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
ret = btrfs_find_item(fs_info->tree_root, path, BTRFS_ORPHAN_OBJECTID,
|
||||
location->objectid, BTRFS_ORPHAN_ITEM_KEY, NULL);
|
||||
btrfs_free_path(path);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
if (ret == 0)
|
||||
|
|
|
@ -1257,10 +1257,19 @@ static int insert_orphan_item(struct btrfs_trans_handle *trans,
|
|||
struct btrfs_root *root, u64 offset)
|
||||
{
|
||||
int ret;
|
||||
ret = btrfs_find_item(root, NULL, BTRFS_ORPHAN_OBJECTID,
|
||||
struct btrfs_path *path;
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = btrfs_find_item(root, path, BTRFS_ORPHAN_OBJECTID,
|
||||
offset, BTRFS_ORPHAN_ITEM_KEY, NULL);
|
||||
if (ret > 0)
|
||||
ret = btrfs_insert_orphan_item(trans, root, offset);
|
||||
|
||||
btrfs_free_path(path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue