Merge branch 'stable/bug.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / fs / btrfs / ctree.c
index b6cbeed..2e66786 100644 (file)
@@ -43,8 +43,6 @@ struct btrfs_path *btrfs_alloc_path(void)
 {
        struct btrfs_path *path;
        path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS);
-       if (path)
-               path->reada = 1;
        return path;
 }
 
@@ -1224,11 +1222,13 @@ static void reada_for_search(struct btrfs_root *root,
        u64 search;
        u64 target;
        u64 nread = 0;
+       u64 gen;
        int direction = path->reada;
        struct extent_buffer *eb;
        u32 nr;
        u32 blocksize;
        u32 nscan = 0;
+       bool map = true;
 
        if (level != 1)
                return;
@@ -1250,7 +1250,19 @@ static void reada_for_search(struct btrfs_root *root,
 
        nritems = btrfs_header_nritems(node);
        nr = slot;
+       if (node->map_token || path->skip_locking)
+               map = false;
+
        while (1) {
+               if (map && !node->map_token) {
+                       unsigned long offset = btrfs_node_key_ptr_offset(nr);
+                       map_private_extent_buffer(node, offset,
+                                                 sizeof(struct btrfs_key_ptr),
+                                                 &node->map_token,
+                                                 &node->kaddr,
+                                                 &node->map_start,
+                                                 &node->map_len, KM_USER1);
+               }
                if (direction < 0) {
                        if (nr == 0)
                                break;
@@ -1268,14 +1280,23 @@ static void reada_for_search(struct btrfs_root *root,
                search = btrfs_node_blockptr(node, nr);
                if ((search <= target && target - search <= 65536) ||
                    (search > target && search - target <= 65536)) {
-                       readahead_tree_block(root, search, blocksize,
-                                    btrfs_node_ptr_generation(node, nr));
+                       gen = btrfs_node_ptr_generation(node, nr);
+                       if (map && node->map_token) {
+                               unmap_extent_buffer(node, node->map_token,
+                                                   KM_USER1);
+                               node->map_token = NULL;
+                       }
+                       readahead_tree_block(root, search, blocksize, gen);
                        nread += blocksize;
                }
                nscan++;
                if ((nread > 65536 || nscan > 32))
                        break;
        }
+       if (map && node->map_token) {
+               unmap_extent_buffer(node, node->map_token, KM_USER1);
+               node->map_token = NULL;
+       }
 }
 
 /*
@@ -1648,9 +1669,6 @@ again:
                }
 cow_done:
                BUG_ON(!cow && ins_len);
-               if (level != btrfs_header_level(b))
-                       WARN_ON(1);
-               level = btrfs_header_level(b);
 
                p->nodes[level] = b;
                if (!p->skip_locking)
@@ -3211,7 +3229,6 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
                        struct btrfs_path *path,
                        u32 new_size, int from_end)
 {
-       int ret = 0;
        int slot;
        struct extent_buffer *leaf;
        struct btrfs_item *item;
@@ -3309,12 +3326,11 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
        btrfs_set_item_size(leaf, item, new_size);
        btrfs_mark_buffer_dirty(leaf);
 
-       ret = 0;
        if (btrfs_leaf_free_space(root, leaf) < 0) {
                btrfs_print_leaf(root, leaf);
                BUG();
        }
-       return ret;
+       return 0;
 }
 
 /*
@@ -3324,7 +3340,6 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
                      struct btrfs_root *root, struct btrfs_path *path,
                      u32 data_size)
 {
-       int ret = 0;
        int slot;
        struct extent_buffer *leaf;
        struct btrfs_item *item;
@@ -3389,12 +3404,11 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
        btrfs_set_item_size(leaf, item, old_size + data_size);
        btrfs_mark_buffer_dirty(leaf);
 
-       ret = 0;
        if (btrfs_leaf_free_space(root, leaf) < 0) {
                btrfs_print_leaf(root, leaf);
                BUG();
        }
-       return ret;
+       return 0;
 }
 
 /*