During deletes and truncate, remove many items at once from the tree
This commit is contained in:
parent
bb7055ec21
commit
cbf87cad07
38
ctree.c
38
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;
|
||||
}
|
||||
|
|
12
ctree.h
12
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
|
||||
|
|
Loading…
Reference in New Issue