aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-01-29 15:11:36 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:00 -0400
commit85e21bac165b4ba1f6f90431ad6fc658ffcbaf3a (patch)
tree6483417c9e5c4f3434fd9f2e7e117a4dc46b94c6 /fs/btrfs/ctree.c
parent70dec8079d78691e476cc6c7cede40656078ad30 (diff)
Btrfs: During deletes and truncate, remove many items at once from the tree
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c38
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 */
2517int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, 2517int 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 }