]> git.hungrycats.org Git - linux/commitdiff
Btrfs: fix invalid leaf slot access in btrfs_lookup_extent()
authorFilipe Manana <fdmanana@suse.com>
Mon, 27 Oct 2014 10:44:24 +0000 (10:44 +0000)
committerZygo Blaxell <zblaxell@serenity.furryterror.org>
Sun, 9 Nov 2014 19:04:29 +0000 (14:04 -0500)
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>
(cherry picked from commit 1a4ed8fdca077d2489ec47d548451be69389e926)

fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/tree-log.c

index 8e29b614fe93d9b8cc22c9eb5d54377d617bb9e7..40ac096eeb4203e6da8e206f28d142403645bdc3 100644 (file)
@@ -3287,7 +3287,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
                           struct btrfs_root *root, unsigned long count);
 int btrfs_async_run_delayed_refs(struct btrfs_root *root,
                                 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,
                             struct btrfs_root *root, u64 bytenr,
                             u64 offset, int metadata, u64 *refs, u64 *flags);
index 98042c1a48b4cb5b25f02dc8adb7c8d9bf5e5fab..b358db12c648559b297563d95839826c9ac9ef08 100644 (file)
@@ -710,8 +710,8 @@ void btrfs_clear_space_info_full(struct btrfs_fs_info *info)
        rcu_read_unlock();
 }
 
-/* simple helper to search for an existing extent at a given offset */
-int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len)
+/* simple helper to search for an existing data extent at a given offset */
+int btrfs_lookup_data_extent(struct btrfs_root *root, u64 start, u64 len)
 {
        int ret;
        struct btrfs_key key;
@@ -726,12 +726,6 @@ int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len)
        key.type = BTRFS_EXTENT_ITEM_KEY;
        ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path,
                                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);
        return ret;
 }
index 1d1ba083ca6ecc1497bd1c141a431a2d5fa26cd9..2038f65a2328d0b5f3eabc7e7f04e0fd983a0742 100644 (file)
@@ -671,7 +671,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
                         * is this extent already allocated in the extent
                         * 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);
                        if (ret == 0) {
                                ret = btrfs_inc_extent_ref(trans, root,