diff options
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 43d23148a4fe..84ad53e06b3a 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -2514,34 +2514,36 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2514 | * delete the item at the leaf level in path. If that empties | 2514 | * delete the item at the leaf level in path. If that empties |
2515 | * the leaf, remove it from the tree | 2515 | * the leaf, remove it from the tree |
2516 | */ | 2516 | */ |
2517 | int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 2517 | int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
2518 | struct btrfs_path *path) | 2518 | struct btrfs_path *path, int slot, int nr) |
2519 | { | 2519 | { |
2520 | int slot; | ||
2521 | struct extent_buffer *leaf; | 2520 | struct extent_buffer *leaf; |
2522 | struct btrfs_item *item; | 2521 | struct btrfs_item *item; |
2523 | int doff; | 2522 | int last_off; |
2524 | int dsize; | 2523 | int dsize = 0; |
2525 | int ret = 0; | 2524 | int ret = 0; |
2526 | int wret; | 2525 | int wret; |
2526 | int i; | ||
2527 | u32 nritems; | 2527 | u32 nritems; |
2528 | 2528 | ||
2529 | leaf = path->nodes[0]; | 2529 | leaf = path->nodes[0]; |
2530 | slot = path->slots[0]; | 2530 | last_off = btrfs_item_offset_nr(leaf, slot + nr - 1); |
2531 | doff = btrfs_item_offset_nr(leaf, slot); | 2531 | |
2532 | dsize = btrfs_item_size_nr(leaf, slot); | 2532 | for (i = 0; i < nr; i++) |
2533 | dsize += btrfs_item_size_nr(leaf, slot + i); | ||
2534 | |||
2533 | nritems = btrfs_header_nritems(leaf); | 2535 | nritems = btrfs_header_nritems(leaf); |
2534 | 2536 | ||
2535 | if (slot != nritems - 1) { | 2537 | if (slot + nr != nritems) { |
2536 | int i; | 2538 | int i; |
2537 | int data_end = leaf_data_end(root, leaf); | 2539 | int data_end = leaf_data_end(root, leaf); |
2538 | 2540 | ||
2539 | memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + | 2541 | memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + |
2540 | data_end + dsize, | 2542 | data_end + dsize, |
2541 | btrfs_leaf_data(leaf) + data_end, | 2543 | btrfs_leaf_data(leaf) + data_end, |
2542 | doff - data_end); | 2544 | last_off - data_end); |
2543 | 2545 | ||
2544 | for (i = slot + 1; i < nritems; i++) { | 2546 | for (i = slot + nr; i < nritems; i++) { |
2545 | u32 ioff; | 2547 | u32 ioff; |
2546 | 2548 | ||
2547 | item = btrfs_item_nr(leaf, i); | 2549 | item = btrfs_item_nr(leaf, i); |
@@ -2562,12 +2564,12 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2562 | } | 2564 | } |
2563 | 2565 | ||
2564 | memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot), | 2566 | memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot), |
2565 | btrfs_item_nr_offset(slot + 1), | 2567 | btrfs_item_nr_offset(slot + nr), |
2566 | sizeof(struct btrfs_item) * | 2568 | sizeof(struct btrfs_item) * |
2567 | (nritems - slot - 1)); | 2569 | (nritems - slot - nr)); |
2568 | } | 2570 | } |
2569 | btrfs_set_header_nritems(leaf, nritems - 1); | 2571 | btrfs_set_header_nritems(leaf, nritems - nr); |
2570 | nritems--; | 2572 | nritems -= nr; |
2571 | 2573 | ||
2572 | /* delete the leaf if we've emptied it */ | 2574 | /* delete the leaf if we've emptied it */ |
2573 | if (nritems == 0) { | 2575 | if (nritems == 0) { |
@@ -2600,7 +2602,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2600 | } | 2602 | } |
2601 | 2603 | ||
2602 | /* delete the leaf if it is mostly empty */ | 2604 | /* delete the leaf if it is mostly empty */ |
2603 | if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { | 2605 | if (used < BTRFS_LEAF_DATA_SIZE(root) / 4) { |
2604 | /* push_leaf_left fixes the path. | 2606 | /* push_leaf_left fixes the path. |
2605 | * make sure the path still points to our leaf | 2607 | * make sure the path still points to our leaf |
2606 | * for possible call to del_ptr below | 2608 | * for possible call to del_ptr below |
@@ -2608,13 +2610,13 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2608 | slot = path->slots[1]; | 2610 | slot = path->slots[1]; |
2609 | extent_buffer_get(leaf); | 2611 | extent_buffer_get(leaf); |
2610 | 2612 | ||
2611 | wret = push_leaf_right(trans, root, path, 1, 1); | 2613 | wret = push_leaf_left(trans, root, path, 1, 1); |
2612 | if (wret < 0 && wret != -ENOSPC) | 2614 | if (wret < 0 && wret != -ENOSPC) |
2613 | ret = wret; | 2615 | ret = wret; |
2614 | 2616 | ||
2615 | if (path->nodes[0] == leaf && | 2617 | if (path->nodes[0] == leaf && |
2616 | btrfs_header_nritems(leaf)) { | 2618 | btrfs_header_nritems(leaf)) { |
2617 | wret = push_leaf_left(trans, root, path, 1, 1); | 2619 | wret = push_leaf_right(trans, root, path, 1, 1); |
2618 | if (wret < 0 && wret != -ENOSPC) | 2620 | if (wret < 0 && wret != -ENOSPC) |
2619 | ret = wret; | 2621 | ret = wret; |
2620 | } | 2622 | } |