aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2014-10-27 06:44:24 -0400
committerChris Mason <clm@fb.com>2014-10-27 16:16:52 -0400
commit1a4ed8fdca077d2489ec47d548451be69389e926 (patch)
treefeee30ff76593fde7a28fa24a70dbbcc097c24a3 /fs
parent21e7626b12f25770e2975bc7c7b2e1d5b1d58a57 (diff)
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: Filipe Manana <fdmanana@suse.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/extent-tree.c10
-rw-r--r--fs/btrfs/tree-log.c2
3 files changed, 4 insertions, 10 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index d557264ee974..fe69edda11fb 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3276,7 +3276,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
3276 struct btrfs_root *root, unsigned long count); 3276 struct btrfs_root *root, unsigned long count);
3277int btrfs_async_run_delayed_refs(struct btrfs_root *root, 3277int btrfs_async_run_delayed_refs(struct btrfs_root *root,
3278 unsigned long count, int wait); 3278 unsigned long count, int wait);
3279int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len); 3279int btrfs_lookup_data_extent(struct btrfs_root *root, u64 start, u64 len);
3280int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, 3280int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
3281 struct btrfs_root *root, u64 bytenr, 3281 struct btrfs_root *root, u64 bytenr,
3282 u64 offset, int metadata, u64 *refs, u64 *flags); 3282 u64 offset, int metadata, u64 *refs, u64 *flags);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 0d599ba1aaed..87c0b46f8a7e 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -710,8 +710,8 @@ void btrfs_clear_space_info_full(struct btrfs_fs_info *info)
710 rcu_read_unlock(); 710 rcu_read_unlock();
711} 711}
712 712
713/* simple helper to search for an existing extent at a given offset */ 713/* simple helper to search for an existing data extent at a given offset */
714int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len) 714int btrfs_lookup_data_extent(struct btrfs_root *root, u64 start, u64 len)
715{ 715{
716 int ret; 716 int ret;
717 struct btrfs_key key; 717 struct btrfs_key key;
@@ -726,12 +726,6 @@ int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len)
726 key.type = BTRFS_EXTENT_ITEM_KEY; 726 key.type = BTRFS_EXTENT_ITEM_KEY;
727 ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path, 727 ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path,
728 0, 0); 728 0, 0);
729 if (ret > 0) {
730 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
731 if (key.objectid == start &&
732 key.type == BTRFS_METADATA_ITEM_KEY)
733 ret = 0;
734 }
735 btrfs_free_path(path); 729 btrfs_free_path(path);
736 return ret; 730 return ret;
737} 731}
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 2b26dad35d88..6d58d72705ae 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -672,7 +672,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
672 * is this extent already allocated in the extent 672 * is this extent already allocated in the extent
673 * allocation tree? If so, just add a reference 673 * allocation tree? If so, just add a reference
674 */ 674 */
675 ret = btrfs_lookup_extent(root, ins.objectid, 675 ret = btrfs_lookup_data_extent(root, ins.objectid,
676 ins.offset); 676 ins.offset);
677 if (ret == 0) { 677 if (ret == 0) {
678 ret = btrfs_inc_extent_ref(trans, root, 678 ret = btrfs_inc_extent_ref(trans, root,