]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/btrfs/ctree.c
Merge branch 'master' into tk71
[mv-sheeva.git] / fs / btrfs / ctree.c
index c3df14ce2cc2c00d232028d1238121ff9c37e35c..b5baff0dccfec40c360397c0d1e47380aea51ae2 100644 (file)
@@ -105,6 +105,8 @@ noinline void btrfs_clear_path_blocking(struct btrfs_path *p,
 /* this also releases the path */
 void btrfs_free_path(struct btrfs_path *p)
 {
+       if (!p)
+               return;
        btrfs_release_path(NULL, p);
        kmem_cache_free(btrfs_path_cachep, p);
 }
@@ -200,7 +202,6 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
                      struct extent_buffer **cow_ret, u64 new_root_objectid)
 {
        struct extent_buffer *cow;
-       u32 nritems;
        int ret = 0;
        int level;
        struct btrfs_disk_key disk_key;
@@ -210,7 +211,6 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
        WARN_ON(root->ref_cows && trans->transid != root->last_trans);
 
        level = btrfs_header_level(buf);
-       nritems = btrfs_header_nritems(buf);
        if (level == 0)
                btrfs_item_key(buf, &disk_key, 0);
        else
@@ -1008,7 +1008,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
        int wret;
        int pslot;
        int orig_slot = path->slots[level];
-       int err_on_enospc = 0;
        u64 orig_ptr;
 
        if (level == 0)
@@ -1071,8 +1070,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
            BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
                return 0;
 
-       if (btrfs_header_nritems(mid) < 2)
-               err_on_enospc = 1;
+       btrfs_header_nritems(mid);
 
        left = read_node_slot(root, parent, pslot - 1);
        if (left) {
@@ -1103,8 +1101,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
                wret = push_node_left(trans, root, left, mid, 1);
                if (wret < 0)
                        ret = wret;
-               if (btrfs_header_nritems(mid) < 2)
-                       err_on_enospc = 1;
+               btrfs_header_nritems(mid);
        }
 
        /*
@@ -1224,14 +1221,12 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
        int wret;
        int pslot;
        int orig_slot = path->slots[level];
-       u64 orig_ptr;
 
        if (level == 0)
                return 1;
 
        mid = path->nodes[level];
        WARN_ON(btrfs_header_generation(mid) != trans->transid);
-       orig_ptr = btrfs_node_blockptr(mid, orig_slot);
 
        if (level < BTRFS_MAX_LEVEL - 1)
                parent = path->nodes[level + 1];
@@ -1577,13 +1572,33 @@ read_block_for_search(struct btrfs_trans_handle *trans,
        blocksize = btrfs_level_size(root, level - 1);
 
        tmp = btrfs_find_tree_block(root, blocknr, blocksize);
-       if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
-               /*
-                * we found an up to date block without sleeping, return
-                * right away
-                */
-               *eb_ret = tmp;
-               return 0;
+       if (tmp) {
+               if (btrfs_buffer_uptodate(tmp, 0)) {
+                       if (btrfs_buffer_uptodate(tmp, gen)) {
+                               /*
+                                * we found an up to date block without
+                                * sleeping, return
+                                * right away
+                                */
+                               *eb_ret = tmp;
+                               return 0;
+                       }
+                       /* the pages were up to date, but we failed
+                        * the generation number check.  Do a full
+                        * read for the generation number that is correct.
+                        * We must do this without dropping locks so
+                        * we can trust our generation number
+                        */
+                       free_extent_buffer(tmp);
+                       tmp = read_tree_block(root, blocknr, blocksize, gen);
+                       if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
+                               *eb_ret = tmp;
+                               return 0;
+                       }
+                       free_extent_buffer(tmp);
+                       btrfs_release_path(NULL, p);
+                       return -EIO;
+               }
        }
 
        /*
@@ -1596,8 +1611,7 @@ read_block_for_search(struct btrfs_trans_handle *trans,
        btrfs_unlock_up_safe(p, level + 1);
        btrfs_set_path_blocking(p);
 
-       if (tmp)
-               free_extent_buffer(tmp);
+       free_extent_buffer(tmp);
        if (p->reada)
                reada_for_search(root, p, level, slot, key->objectid);
 
@@ -2502,6 +2516,9 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
        btrfs_assert_tree_locked(path->nodes[1]);
 
        right = read_node_slot(root, upper, slot + 1);
+       if (right == NULL)
+               return 1;
+
        btrfs_tree_lock(right);
        btrfs_set_lock_blocking(right);
 
@@ -2548,7 +2565,6 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
 {
        struct btrfs_disk_key disk_key;
        struct extent_buffer *right = path->nodes[0];
-       int slot;
        int i;
        int push_space = 0;
        int push_items = 0;
@@ -2560,8 +2576,6 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
        u32 this_item_size;
        u32 old_left_item_size;
 
-       slot = path->slots[1];
-
        if (empty)
                nr = min(right_nritems, max_slot);
        else
@@ -2755,6 +2769,9 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
        btrfs_assert_tree_locked(path->nodes[1]);
 
        left = read_node_slot(root, path->nodes[1], slot - 1);
+       if (left == NULL)
+               return 1;
+
        btrfs_tree_lock(left);
        btrfs_set_lock_blocking(left);
 
@@ -3330,7 +3347,6 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
 {
        int ret = 0;
        int slot;
-       int slot_orig;
        struct extent_buffer *leaf;
        struct btrfs_item *item;
        u32 nritems;
@@ -3340,7 +3356,6 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
        unsigned int size_diff;
        int i;
 
-       slot_orig = path->slots[0];
        leaf = path->nodes[0];
        slot = path->slots[0];
 
@@ -3445,7 +3460,6 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
 {
        int ret = 0;
        int slot;
-       int slot_orig;
        struct extent_buffer *leaf;
        struct btrfs_item *item;
        u32 nritems;
@@ -3454,7 +3468,6 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
        unsigned int old_size;
        int i;
 
-       slot_orig = path->slots[0];
        leaf = path->nodes[0];
 
        nritems = btrfs_header_nritems(leaf);
@@ -3787,7 +3800,6 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
                            struct btrfs_key *cpu_key, u32 *data_size,
                            int nr)
 {
-       struct extent_buffer *leaf;
        int ret = 0;
        int slot;
        int i;
@@ -3804,7 +3816,6 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
        if (ret < 0)
                goto out;
 
-       leaf = path->nodes[0];
        slot = path->slots[0];
        BUG_ON(slot < 0);