summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-01-29 15:11:36 -0500
committerDavid Woodhouse <dwmw2@hera.kernel.org>2008-01-29 15:11:36 -0500
commitcbf87cad0752748e38bf98f1d18614e0be6dc500 (patch)
treed1a92e4a25dfada5ef50f9dec7174db4fceae01d
parentbb7055ec21bc89814d92683cc40a9f66812aeb84 (diff)
During deletes and truncate, remove many items at once from the tree
-rw-r--r--ctree.c38
-rw-r--r--ctree.h12
2 files changed, 30 insertions, 20 deletions
diff --git a/ctree.c b/ctree.c
index 94836618..63575809 100644
--- a/ctree.c
+++ b/ctree.c
@@ -2368,34 +2368,36 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
* delete the item at the leaf level in path. If that empties
* the leaf, remove it from the tree
*/
-int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
- struct btrfs_path *path)
+int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+ struct btrfs_path *path, int slot, int nr)
{
- int slot;
struct extent_buffer *leaf;
struct btrfs_item *item;
- int doff;
- int dsize;
+ int last_off;
+ int dsize = 0;
int ret = 0;
int wret;
+ int i;
u32 nritems;
leaf = path->nodes[0];
- slot = path->slots[0];
- doff = btrfs_item_offset_nr(leaf, slot);
- dsize = btrfs_item_size_nr(leaf, slot);
+ last_off = btrfs_item_offset_nr(leaf, slot + nr - 1);
+
+ for (i = 0; i < nr; i++)
+ dsize += btrfs_item_size_nr(leaf, slot + i);
+
nritems = btrfs_header_nritems(leaf);
- if (slot != nritems - 1) {
+ if (slot + nr != nritems) {
int i;
int data_end = leaf_data_end(root, leaf);
memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
data_end + dsize,
btrfs_leaf_data(leaf) + data_end,
- doff - data_end);
+ last_off - data_end);
- for (i = slot + 1; i < nritems; i++) {
+ for (i = slot + nr; i < nritems; i++) {
u32 ioff;
item = btrfs_item_nr(leaf, i);
@@ -2404,12 +2406,12 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
}
memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot),
- btrfs_item_nr_offset(slot + 1),
+ btrfs_item_nr_offset(slot + nr),
sizeof(struct btrfs_item) *
- (nritems - slot - 1));
+ (nritems - slot - nr));
}
- btrfs_set_header_nritems(leaf, nritems - 1);
- nritems--;
+ btrfs_set_header_nritems(leaf, nritems - nr);
+ nritems -= nr;
/* delete the leaf if we've emptied it */
if (nritems == 0) {
@@ -2442,7 +2444,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
}
/* delete the leaf if it is mostly empty */
- if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) {
+ if (used < BTRFS_LEAF_DATA_SIZE(root) / 4) {
/* push_leaf_left fixes the path.
* make sure the path still points to our leaf
* for possible call to del_ptr below
@@ -2450,13 +2452,13 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
slot = path->slots[1];
extent_buffer_get(leaf);
- wret = push_leaf_right(trans, root, path, 1, 1);
+ wret = push_leaf_left(trans, root, path, 1, 1);
if (wret < 0 && wret != -ENOSPC)
ret = wret;
if (path->nodes[0] == leaf &&
btrfs_header_nritems(leaf)) {
- wret = push_leaf_left(trans, root, path, 1, 1);
+ wret = push_leaf_right(trans, root, path, 1, 1);
if (wret < 0 && wret != -ENOSPC)
ret = wret;
}
diff --git a/ctree.h b/ctree.h
index 1166f946..a219c23f 100644
--- a/ctree.h
+++ b/ctree.h
@@ -997,8 +997,16 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p);
struct btrfs_path *btrfs_alloc_path(void);
void btrfs_free_path(struct btrfs_path *p);
void btrfs_init_path(struct btrfs_path *p);
-int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
- struct btrfs_path *path);
+int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+ struct btrfs_path *path, int slot, int nr);
+
+static inline int btrfs_del_item(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct btrfs_path *path)
+{
+ return btrfs_del_items(trans, root, path, path->slots[0], 1);
+}
+
int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
*root, struct btrfs_key *key, void *data, u32 data_size);
int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root