Btrfs: still corruption hunting
[deliverable/linux.git] / fs / btrfs / ctree.c
index b33a6bfaf327dab34aa4a358d2f4accfb10201a7..453ce835209ae437772ca404e2213d3a474dd01e 100644 (file)
@@ -16,6 +16,16 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct
 static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                   struct btrfs_path *path, int level, int slot);
 
+struct btrfs_path *btrfs_alloc_path(void)
+{
+       return kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS);
+}
+
+void btrfs_free_path(struct btrfs_path *p)
+{
+       kmem_cache_free(btrfs_path_cachep, p);
+}
+
 inline void btrfs_init_path(struct btrfs_path *p)
 {
        memset(p, 0, sizeof(*p));
@@ -47,25 +57,27 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
        }
        cow = btrfs_alloc_free_block(trans, root);
        cow_node = btrfs_buffer_node(cow);
+       if (buf->b_size != root->blocksize || cow->b_size != root->blocksize)
+               WARN_ON(1);
        memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
        btrfs_set_header_blocknr(&cow_node->header, cow->b_blocknr);
        btrfs_set_header_generation(&cow_node->header, trans->transid);
-       *cow_ret = cow;
-       mark_buffer_dirty(cow);
        btrfs_inc_ref(trans, root, buf);
        if (buf == root->node) {
                root->node = cow;
                get_bh(cow);
-               if (buf != root->commit_root)
+               if (buf != root->commit_root) {
                        btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1);
+               }
                btrfs_block_release(root, buf);
        } else {
                btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot,
                                        cow->b_blocknr);
-               mark_buffer_dirty(parent);
+               btrfs_mark_buffer_dirty(parent);
                btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1);
        }
        btrfs_block_release(root, buf);
+       *cow_ret = cow;
        return 0;
 }
 
@@ -109,14 +121,14 @@ static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
                return 1;
        if (k1.objectid < k2->objectid)
                return -1;
-       if (k1.flags > k2->flags)
-               return 1;
-       if (k1.flags < k2->flags)
-               return -1;
        if (k1.offset > k2->offset)
                return 1;
        if (k1.offset < k2->offset)
                return -1;
+       if (k1.flags > k2->flags)
+               return 1;
+       if (k1.flags < k2->flags)
+               return -1;
        return 0;
 }
 
@@ -312,11 +324,12 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
                BUG_ON(!child);
                root->node = child;
                path->nodes[level] = NULL;
+               clean_tree_block(trans, root, mid_buf);
+               wait_on_buffer(mid_buf);
                /* once for the path */
                btrfs_block_release(root, mid_buf);
                /* once for the root ptr */
                btrfs_block_release(root, mid_buf);
-               clean_tree_block(trans, root, mid_buf);
                return btrfs_free_extent(trans, root, blocknr, 1, 1);
        }
        parent = btrfs_buffer_node(parent_buf);
@@ -351,8 +364,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
                        ret = wret;
                if (btrfs_header_nritems(&right->header) == 0) {
                        u64 blocknr = right_buf->b_blocknr;
-                       btrfs_block_release(root, right_buf);
                        clean_tree_block(trans, root, right_buf);
+                       wait_on_buffer(right_buf);
+                       btrfs_block_release(root, right_buf);
                        right_buf = NULL;
                        right = NULL;
                        wret = del_ptr(trans, root, path, level + 1, pslot +
@@ -363,10 +377,11 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
                        if (wret)
                                ret = wret;
                } else {
-                       memcpy(&parent->ptrs[pslot + 1].key,
-                               &right->ptrs[0].key,
-                               sizeof(struct btrfs_disk_key));
-                       mark_buffer_dirty(parent_buf);
+                       btrfs_memcpy(root, parent,
+                                    &parent->ptrs[pslot + 1].key,
+                                    &right->ptrs[0].key,
+                                    sizeof(struct btrfs_disk_key));
+                       btrfs_mark_buffer_dirty(parent_buf);
                }
        }
        if (btrfs_header_nritems(&mid->header) == 1) {
@@ -388,8 +403,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
        if (btrfs_header_nritems(&mid->header) == 0) {
                /* we've managed to empty the middle node, drop it */
                u64 blocknr = mid_buf->b_blocknr;
-               btrfs_block_release(root, mid_buf);
                clean_tree_block(trans, root, mid_buf);
+               wait_on_buffer(mid_buf);
+               btrfs_block_release(root, mid_buf);
                mid_buf = NULL;
                mid = NULL;
                wret = del_ptr(trans, root, path, level + 1, pslot);
@@ -400,9 +416,10 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
                        ret = wret;
        } else {
                /* update the parent key to reflect our changes */
-               memcpy(&parent->ptrs[pslot].key, &mid->ptrs[0].key,
-                      sizeof(struct btrfs_disk_key));
-               mark_buffer_dirty(parent_buf);
+               btrfs_memcpy(root, parent,
+                            &parent->ptrs[pslot].key, &mid->ptrs[0].key,
+                            sizeof(struct btrfs_disk_key));
+               btrfs_mark_buffer_dirty(parent_buf);
        }
 
        /* update the path */
@@ -457,6 +474,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
        int ret;
        int level;
 
+       WARN_ON(p->nodes[0] != NULL);
+       WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex));
 again:
        b = root->node;
        get_bh(b);
@@ -470,9 +489,12 @@ again:
                                               p->slots[level + 1],
                                               &cow_buf);
                        b = cow_buf;
+                       c = btrfs_buffer_node(b);
                }
                BUG_ON(!cow && ins_len);
-               c = btrfs_buffer_node(b);
+               if (level != btrfs_header_level(&c->header))
+                       WARN_ON(1);
+               level = btrfs_header_level(&c->header);
                p->nodes[level] = b;
                ret = check_block(root, p, level);
                if (ret)
@@ -542,8 +564,8 @@ static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root
                if (!path->nodes[i])
                        break;
                t = btrfs_buffer_node(path->nodes[i]);
-               memcpy(&t->ptrs[tslot].key, key, sizeof(*key));
-               mark_buffer_dirty(path->nodes[i]);
+               btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key));
+               btrfs_mark_buffer_dirty(path->nodes[i]);
                if (tslot != 0)
                        break;
        }
@@ -578,17 +600,17 @@ static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
        if (src_nritems < push_items)
                push_items = src_nritems;
 
-       memcpy(dst->ptrs + dst_nritems, src->ptrs,
-               push_items * sizeof(struct btrfs_key_ptr));
+       btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs,
+                    push_items * sizeof(struct btrfs_key_ptr));
        if (push_items < src_nritems) {
-               memmove(src->ptrs, src->ptrs + push_items,
+               btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items,
                        (src_nritems - push_items) *
                        sizeof(struct btrfs_key_ptr));
        }
        btrfs_set_header_nritems(&src->header, src_nritems - push_items);
        btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
-       mark_buffer_dirty(src_buf);
-       mark_buffer_dirty(dst_buf);
+       btrfs_mark_buffer_dirty(src_buf);
+       btrfs_mark_buffer_dirty(dst_buf);
        return ret;
 }
 
@@ -627,16 +649,18 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct
        if (max_push < push_items)
                push_items = max_push;
 
-       memmove(dst->ptrs + push_items, dst->ptrs,
-               dst_nritems * sizeof(struct btrfs_key_ptr));
-       memcpy(dst->ptrs, src->ptrs + src_nritems - push_items,
-               push_items * sizeof(struct btrfs_key_ptr));
+       btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs,
+                     dst_nritems * sizeof(struct btrfs_key_ptr));
+
+       btrfs_memcpy(root, dst, dst->ptrs,
+                    src->ptrs + src_nritems - push_items,
+                    push_items * sizeof(struct btrfs_key_ptr));
 
        btrfs_set_header_nritems(&src->header, src_nritems - push_items);
        btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
 
-       mark_buffer_dirty(src_buf);
-       mark_buffer_dirty(dst_buf);
+       btrfs_mark_buffer_dirty(src_buf);
+       btrfs_mark_buffer_dirty(dst_buf);
        return ret;
 }
 
@@ -672,10 +696,11 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
                lower_key = &((struct btrfs_leaf *)lower)->items[0].key;
        else
                lower_key = &lower->ptrs[0].key;
-       memcpy(&c->ptrs[0].key, lower_key, sizeof(struct btrfs_disk_key));
+       btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key,
+                    sizeof(struct btrfs_disk_key));
        btrfs_set_node_blockptr(c, 0, path->nodes[level - 1]->b_blocknr);
 
-       mark_buffer_dirty(t);
+       btrfs_mark_buffer_dirty(t);
 
        /* the super has an extra ref to root->node */
        btrfs_block_release(root, root->node);
@@ -710,13 +735,15 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
        if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
                BUG();
        if (slot != nritems) {
-               memmove(lower->ptrs + slot + 1, lower->ptrs + slot,
-                       (nritems - slot) * sizeof(struct btrfs_key_ptr));
+               btrfs_memmove(root, lower, lower->ptrs + slot + 1,
+                             lower->ptrs + slot,
+                             (nritems - slot) * sizeof(struct btrfs_key_ptr));
        }
-       memcpy(&lower->ptrs[slot].key, key, sizeof(struct btrfs_disk_key));
+       btrfs_memcpy(root, lower, &lower->ptrs[slot].key,
+                    key, sizeof(struct btrfs_disk_key));
        btrfs_set_node_blockptr(lower, slot, blocknr);
        btrfs_set_header_nritems(&lower->header, nritems + 1);
-       mark_buffer_dirty(path->nodes[level]);
+       btrfs_mark_buffer_dirty(path->nodes[level]);
        return 0;
 }
 
@@ -753,19 +780,20 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
        split_buffer = btrfs_alloc_free_block(trans, root);
        split = btrfs_buffer_node(split_buffer);
        btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
+       btrfs_set_header_level(&split->header, btrfs_header_level(&c->header));
        btrfs_set_header_blocknr(&split->header, split_buffer->b_blocknr);
        btrfs_set_header_generation(&split->header, trans->transid);
        btrfs_set_header_parentid(&split->header,
              btrfs_header_parentid(btrfs_buffer_header(root->node)));
        mid = (c_nritems + 1) / 2;
-       memcpy(split->ptrs, c->ptrs + mid,
-               (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
+       btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid,
+                    (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
        btrfs_set_header_nritems(&split->header, c_nritems - mid);
        btrfs_set_header_nritems(&c->header, mid);
        ret = 0;
 
-       mark_buffer_dirty(t);
-       mark_buffer_dirty(split_buffer);
+       btrfs_mark_buffer_dirty(t);
+       btrfs_mark_buffer_dirty(split_buffer);
        wret = insert_ptr(trans, root, path, &split->ptrs[0].key,
                          split_buffer->b_blocknr, path->slots[level + 1] + 1,
                          level + 1);
@@ -872,17 +900,22 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
        push_space = btrfs_item_end(left->items + left_nritems - push_items);
        push_space -= leaf_data_end(root, left);
        /* make room in the right data area */
-       memmove(btrfs_leaf_data(right) + leaf_data_end(root, right) -
-               push_space, btrfs_leaf_data(right) + leaf_data_end(root, right),
-               BTRFS_LEAF_DATA_SIZE(root) - leaf_data_end(root, right));
+       btrfs_memmove(root, right, btrfs_leaf_data(right) +
+                     leaf_data_end(root, right) - push_space,
+                     btrfs_leaf_data(right) +
+                     leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) -
+                     leaf_data_end(root, right));
        /* copy from the left data area */
-       memcpy(btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - push_space,
-               btrfs_leaf_data(left) + leaf_data_end(root, left), push_space);
-       memmove(right->items + push_items, right->items,
+       btrfs_memcpy(root, right, btrfs_leaf_data(right) +
+                    BTRFS_LEAF_DATA_SIZE(root) - push_space,
+                    btrfs_leaf_data(left) + leaf_data_end(root, left),
+                    push_space);
+       btrfs_memmove(root, right, right->items + push_items, right->items,
                right_nritems * sizeof(struct btrfs_item));
        /* copy the items from left to right */
-       memcpy(right->items, left->items + left_nritems - push_items,
-               push_items * sizeof(struct btrfs_item));
+       btrfs_memcpy(root, right, right->items, left->items +
+                    left_nritems - push_items,
+                    push_items * sizeof(struct btrfs_item));
 
        /* update the item pointers */
        right_nritems += push_items;
@@ -896,11 +929,11 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
        left_nritems -= push_items;
        btrfs_set_header_nritems(&left->header, left_nritems);
 
-       mark_buffer_dirty(left_buf);
-       mark_buffer_dirty(right_buf);
-       memcpy(&upper_node->ptrs[slot + 1].key,
+       btrfs_mark_buffer_dirty(left_buf);
+       btrfs_mark_buffer_dirty(right_buf);
+       btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key,
                &right->items[0].key, sizeof(struct btrfs_disk_key));
-       mark_buffer_dirty(upper);
+       btrfs_mark_buffer_dirty(upper);
 
        /* then fixup the leaf pointer in the path */
        if (path->slots[0] >= left_nritems) {
@@ -974,14 +1007,16 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
                return 1;
        }
        /* push data from right to left */
-       memcpy(left->items + btrfs_header_nritems(&left->header),
-               right->items, push_items * sizeof(struct btrfs_item));
+       btrfs_memcpy(root, left, left->items +
+                    btrfs_header_nritems(&left->header),
+                    right->items, push_items * sizeof(struct btrfs_item));
        push_space = BTRFS_LEAF_DATA_SIZE(root) -
                     btrfs_item_offset(right->items + push_items -1);
-       memcpy(btrfs_leaf_data(left) + leaf_data_end(root, left) - push_space,
-               btrfs_leaf_data(right) +
-               btrfs_item_offset(right->items + push_items - 1),
-               push_space);
+       btrfs_memcpy(root, left, btrfs_leaf_data(left) +
+                    leaf_data_end(root, left) - push_space,
+                    btrfs_leaf_data(right) +
+                    btrfs_item_offset(right->items + push_items - 1),
+                    push_space);
        old_left_nritems = btrfs_header_nritems(&left->header);
        BUG_ON(old_left_nritems < 0);
 
@@ -997,10 +1032,11 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
        /* fixup right node */
        push_space = btrfs_item_offset(right->items + push_items - 1) -
                     leaf_data_end(root, right);
-       memmove(btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
-               push_space, btrfs_leaf_data(right) +
-               leaf_data_end(root, right), push_space);
-       memmove(right->items, right->items + push_items,
+       btrfs_memmove(root, right, btrfs_leaf_data(right) +
+                     BTRFS_LEAF_DATA_SIZE(root) - push_space,
+                     btrfs_leaf_data(right) +
+                     leaf_data_end(root, right), push_space);
+       btrfs_memmove(root, right, right->items, right->items + push_items,
                (btrfs_header_nritems(&right->header) - push_items) *
                sizeof(struct btrfs_item));
        btrfs_set_header_nritems(&right->header,
@@ -1014,8 +1050,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
                push_space = btrfs_item_offset(right->items + i);
        }
 
-       mark_buffer_dirty(t);
-       mark_buffer_dirty(right_buf);
+       btrfs_mark_buffer_dirty(t);
+       btrfs_mark_buffer_dirty(right_buf);
 
        wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1);
        if (wret)
@@ -1107,11 +1143,12 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
              btrfs_header_parentid(btrfs_buffer_header(root->node)));
        data_copy_size = btrfs_item_end(l->items + mid) -
                         leaf_data_end(root, l);
-       memcpy(right->items, l->items + mid,
-              (nritems - mid) * sizeof(struct btrfs_item));
-       memcpy(btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
-               data_copy_size, btrfs_leaf_data(l) +
-               leaf_data_end(root, l), data_copy_size);
+       btrfs_memcpy(root, right, right->items, l->items + mid,
+                    (nritems - mid) * sizeof(struct btrfs_item));
+       btrfs_memcpy(root, right,
+                    btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
+                    data_copy_size, btrfs_leaf_data(l) +
+                    leaf_data_end(root, l), data_copy_size);
        rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
                      btrfs_item_end(l->items + mid);
 
@@ -1126,8 +1163,8 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
                          right_buffer->b_blocknr, path->slots[1] + 1, 1);
        if (wret)
                ret = wret;
-       mark_buffer_dirty(right_buffer);
-       mark_buffer_dirty(l_buf);
+       btrfs_mark_buffer_dirty(right_buffer);
+       btrfs_mark_buffer_dirty(l_buf);
        BUG_ON(path->slots[0] != slot);
        if (mid <= slot) {
                btrfs_block_release(root, path->nodes[0]);
@@ -1164,7 +1201,6 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
                BUG();
        ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1);
        if (ret == 0) {
-               btrfs_release_path(root, path);
                return -EEXIST;
        }
        if (ret < 0)
@@ -1198,22 +1234,23 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
                }
 
                /* shift the items */
-               memmove(leaf->items + slot + 1, leaf->items + slot,
-                       (nritems - slot) * sizeof(struct btrfs_item));
+               btrfs_memmove(root, leaf, leaf->items + slot + 1,
+                             leaf->items + slot,
+                             (nritems - slot) * sizeof(struct btrfs_item));
 
                /* shift the data */
-               memmove(btrfs_leaf_data(leaf) + data_end - data_size,
-                       btrfs_leaf_data(leaf) +
-                       data_end, old_data - data_end);
+               btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
+                             data_end - data_size, btrfs_leaf_data(leaf) +
+                             data_end, old_data - data_end);
                data_end = old_data;
        }
        /* setup the item for the new data */
-       memcpy(&leaf->items[slot].key, &disk_key,
-               sizeof(struct btrfs_disk_key));
+       btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key,
+                    sizeof(struct btrfs_disk_key));
        btrfs_set_item_offset(leaf->items + slot, data_end - data_size);
        btrfs_set_item_size(leaf->items + slot, data_size);
        btrfs_set_header_nritems(&leaf->header, nritems + 1);
-       mark_buffer_dirty(leaf_buf);
+       btrfs_mark_buffer_dirty(leaf_buf);
 
        ret = 0;
        if (slot == 0)
@@ -1235,18 +1272,22 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
                      data_size)
 {
        int ret = 0;
-       struct btrfs_path path;
+       struct btrfs_path *path;
        u8 *ptr;
 
-       btrfs_init_path(&path);
-       ret = btrfs_insert_empty_item(trans, root, &path, cpu_key, data_size);
+       path = btrfs_alloc_path();
+       BUG_ON(!path);
+       btrfs_init_path(path);
+       ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
        if (!ret) {
-               ptr = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]),
-                                    path.slots[0], u8);
-               memcpy(ptr, data, data_size);
-               mark_buffer_dirty(path.nodes[0]);
+               ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
+                                    path->slots[0], u8);
+               btrfs_memcpy(root, path->nodes[0]->b_data,
+                            ptr, data, data_size);
+               btrfs_mark_buffer_dirty(path->nodes[0]);
        }
-       btrfs_release_path(root, &path);
+       btrfs_release_path(root, path);
+       btrfs_free_path(path);
        return ret;
 }
 
@@ -1269,8 +1310,10 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
        node = btrfs_buffer_node(parent);
        nritems = btrfs_header_nritems(&node->header);
        if (slot != nritems -1) {
-               memmove(node->ptrs + slot, node->ptrs + slot + 1,
-                       sizeof(struct btrfs_key_ptr) * (nritems - slot - 1));
+               btrfs_memmove(root, node, node->ptrs + slot,
+                             node->ptrs + slot + 1,
+                             sizeof(struct btrfs_key_ptr) *
+                             (nritems - slot - 1));
        }
        nritems--;
        btrfs_set_header_nritems(&node->header, nritems);
@@ -1285,7 +1328,7 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                if (wret)
                        ret = wret;
        }
-       mark_buffer_dirty(parent);
+       btrfs_mark_buffer_dirty(parent);
        return ret;
 }
 
@@ -1315,16 +1358,18 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
        if (slot != nritems - 1) {
                int i;
                int data_end = leaf_data_end(root, leaf);
-               memmove(btrfs_leaf_data(leaf) + data_end + dsize,
-                       btrfs_leaf_data(leaf) + data_end,
-                       doff - data_end);
+               btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
+                             data_end + dsize,
+                             btrfs_leaf_data(leaf) + data_end,
+                             doff - data_end);
                for (i = slot + 1; i < nritems; i++) {
                        u32 ioff = btrfs_item_offset(leaf->items + i);
                        btrfs_set_item_offset(leaf->items + i, ioff + dsize);
                }
-               memmove(leaf->items + slot, leaf->items + slot + 1,
-                       sizeof(struct btrfs_item) *
-                       (nritems - slot - 1));
+               btrfs_memmove(root, leaf, leaf->items + slot,
+                             leaf->items + slot + 1,
+                             sizeof(struct btrfs_item) *
+                             (nritems - slot - 1));
        }
        btrfs_set_header_nritems(&leaf->header, nritems - 1);
        nritems--;
@@ -1334,6 +1379,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                        btrfs_set_header_level(&leaf->header, 0);
                } else {
                        clean_tree_block(trans, root, leaf_buf);
+                       wait_on_buffer(leaf_buf);
                        wret = del_ptr(trans, root, path, 1, path->slots[1]);
                        if (wret)
                                ret = wret;
@@ -1371,6 +1417,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                        if (btrfs_header_nritems(&leaf->header) == 0) {
                                u64 blocknr = leaf_buf->b_blocknr;
                                clean_tree_block(trans, root, leaf_buf);
+                               wait_on_buffer(leaf_buf);
                                wret = del_ptr(trans, root, path, 1, slot);
                                if (wret)
                                        ret = wret;
@@ -1380,11 +1427,11 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                                if (wret)
                                        ret = wret;
                        } else {
-                               mark_buffer_dirty(leaf_buf);
+                               btrfs_mark_buffer_dirty(leaf_buf);
                                btrfs_block_release(root, leaf_buf);
                        }
                } else {
-                       mark_buffer_dirty(leaf_buf);
+                       btrfs_mark_buffer_dirty(leaf_buf);
                }
        }
        return ret;
This page took 0.0337 seconds and 5 git commands to generate.