Commit 1a4ed8fd authored by Filipe Manana's avatar Filipe Manana Committed by Chris Mason

Btrfs: fix invalid leaf slot access in btrfs_lookup_extent()

If we couldn't find our extent item, we accessed the current slot
(path->slots[0]) to check if it corresponds to an equivalent skinny
metadata item. However this slot could be beyond our last item in the
leaf (i.e. path->slots[0] >= btrfs_header_nritems(leaf)), in which case
we shouldn't process it.

Since btrfs_lookup_extent() is only used to find extent items for data
extents, fix this by removing completely the logic that looks up for an
equivalent skinny metadata item, since it can not exist.
Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 21e7626b
...@@ -3276,7 +3276,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, ...@@ -3276,7 +3276,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
struct btrfs_root *root, unsigned long count); struct btrfs_root *root, unsigned long count);
int btrfs_async_run_delayed_refs(struct btrfs_root *root, int btrfs_async_run_delayed_refs(struct btrfs_root *root,
unsigned long count, int wait); unsigned long count, int wait);
int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len); int btrfs_lookup_data_extent(struct btrfs_root *root, u64 start, u64 len);
int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 bytenr, struct btrfs_root *root, u64 bytenr,
u64 offset, int metadata, u64 *refs, u64 *flags); u64 offset, int metadata, u64 *refs, u64 *flags);
......
...@@ -710,8 +710,8 @@ void btrfs_clear_space_info_full(struct btrfs_fs_info *info) ...@@ -710,8 +710,8 @@ void btrfs_clear_space_info_full(struct btrfs_fs_info *info)
rcu_read_unlock(); rcu_read_unlock();
} }
/* simple helper to search for an existing extent at a given offset */ /* simple helper to search for an existing data extent at a given offset */
int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len) int btrfs_lookup_data_extent(struct btrfs_root *root, u64 start, u64 len)
{ {
int ret; int ret;
struct btrfs_key key; struct btrfs_key key;
...@@ -726,12 +726,6 @@ int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len) ...@@ -726,12 +726,6 @@ int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len)
key.type = BTRFS_EXTENT_ITEM_KEY; key.type = BTRFS_EXTENT_ITEM_KEY;
ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path, ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path,
0, 0); 0, 0);
if (ret > 0) {
btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
if (key.objectid == start &&
key.type == BTRFS_METADATA_ITEM_KEY)
ret = 0;
}
btrfs_free_path(path); btrfs_free_path(path);
return ret; return ret;
} }
......
...@@ -672,7 +672,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, ...@@ -672,7 +672,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
* is this extent already allocated in the extent * is this extent already allocated in the extent
* allocation tree? If so, just add a reference * allocation tree? If so, just add a reference
*/ */
ret = btrfs_lookup_extent(root, ins.objectid, ret = btrfs_lookup_data_extent(root, ins.objectid,
ins.offset); ins.offset);
if (ret == 0) { if (ret == 0) {
ret = btrfs_inc_extent_ref(trans, root, ret = btrfs_inc_extent_ref(trans, root,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment