Commit 3685f791 authored by Chris Mason's avatar Chris Mason

Btrfs: CPU usage optimizations in push and the extent_map code

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 59d169e2
...@@ -1588,6 +1588,11 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -1588,6 +1588,11 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
if (!path->nodes[1]) if (!path->nodes[1])
return 1; return 1;
right_nritems = btrfs_header_nritems(right);
if (right_nritems == 0) {
return 1;
}
left = read_tree_block(root, btrfs_node_blockptr(path->nodes[1], left = read_tree_block(root, btrfs_node_blockptr(path->nodes[1],
slot - 1), root->leafsize); slot - 1), root->leafsize);
free_space = btrfs_leaf_free_space(root, left); free_space = btrfs_leaf_free_space(root, left);
...@@ -1604,18 +1609,13 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -1604,18 +1609,13 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
free_extent_buffer(left); free_extent_buffer(left);
return 1; return 1;
} }
free_space = btrfs_leaf_free_space(root, left); free_space = btrfs_leaf_free_space(root, left);
if (free_space < data_size + sizeof(struct btrfs_item)) { if (free_space < data_size + sizeof(struct btrfs_item)) {
free_extent_buffer(left); free_extent_buffer(left);
return 1; return 1;
} }
right_nritems = btrfs_header_nritems(right);
if (right_nritems == 0) {
free_extent_buffer(left);
return 1;
}
for (i = 0; i < right_nritems - 1; i++) { for (i = 0; i < right_nritems - 1; i++) {
item = btrfs_item_nr(right, i); item = btrfs_item_nr(right, i);
if (!right->map_token) { if (!right->map_token) {
...@@ -1772,21 +1772,25 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -1772,21 +1772,25 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
struct btrfs_disk_key disk_key; struct btrfs_disk_key disk_key;
/* first try to make some room by pushing left and right */ /* first try to make some room by pushing left and right */
wret = push_leaf_left(trans, root, path, data_size); if (ins_key->type != BTRFS_DIR_ITEM_KEY) {
if (wret < 0) {
return wret;
}
if (wret) {
wret = push_leaf_right(trans, root, path, data_size); wret = push_leaf_right(trans, root, path, data_size);
if (wret < 0) if (wret < 0) {
return wret; return wret;
} }
l = path->nodes[0]; if (wret) {
wret = push_leaf_left(trans, root, path, data_size);
if (wret < 0)
return wret;
}
l = path->nodes[0];
/* did the pushes work? */ /* did the pushes work? */
if (btrfs_leaf_free_space(root, l) >= if (btrfs_leaf_free_space(root, l) >=
sizeof(struct btrfs_item) + data_size) { sizeof(struct btrfs_item) + data_size) {
return 0; return 0;
}
} else {
l = path->nodes[0];
} }
if (!path->nodes[1]) { if (!path->nodes[1]) {
...@@ -2388,13 +2392,13 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, ...@@ -2388,13 +2392,13 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
slot = path->slots[1]; slot = path->slots[1];
extent_buffer_get(leaf); extent_buffer_get(leaf);
wret = push_leaf_left(trans, root, path, 1); wret = push_leaf_right(trans, root, path, 1);
if (wret < 0 && wret != -ENOSPC) if (wret < 0 && wret != -ENOSPC)
ret = wret; ret = wret;
if (path->nodes[0] == leaf && if (path->nodes[0] == leaf &&
btrfs_header_nritems(leaf)) { btrfs_header_nritems(leaf)) {
wret = push_leaf_right(trans, root, path, 1); wret = push_leaf_left(trans, root, path, 1);
if (wret < 0 && wret != -ENOSPC) if (wret < 0 && wret != -ENOSPC)
ret = wret; ret = wret;
} }
......
...@@ -1986,12 +1986,15 @@ static inline struct page *extent_buffer_page(struct extent_buffer *eb, ...@@ -1986,12 +1986,15 @@ static inline struct page *extent_buffer_page(struct extent_buffer *eb,
unsigned long i) unsigned long i)
{ {
struct page *p; struct page *p;
struct address_space *mapping;
if (i == 0) if (i == 0)
return eb->first_page; return eb->first_page;
i += eb->start >> PAGE_CACHE_SHIFT; i += eb->start >> PAGE_CACHE_SHIFT;
p = find_get_page(eb->first_page->mapping, i); mapping = eb->first_page->mapping;
page_cache_release(p); read_lock_irq(&mapping->tree_lock);
p = radix_tree_lookup(&mapping->page_tree, i);
read_unlock_irq(&mapping->tree_lock);
return p; return p;
} }
...@@ -2365,9 +2368,7 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv, ...@@ -2365,9 +2368,7 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv,
WARN_ON(start > eb->len); WARN_ON(start > eb->len);
WARN_ON(start + len > eb->start + eb->len); WARN_ON(start + len > eb->start + eb->len);
offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1); offset = (start_offset + start) & ((unsigned long)PAGE_CACHE_SIZE - 1);
if (i == 0)
offset += start_offset;
while(len > 0) { while(len > 0) {
page = extent_buffer_page(eb, i); page = extent_buffer_page(eb, i);
...@@ -2475,9 +2476,7 @@ int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv, ...@@ -2475,9 +2476,7 @@ int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv,
WARN_ON(start > eb->len); WARN_ON(start > eb->len);
WARN_ON(start + len > eb->start + eb->len); WARN_ON(start + len > eb->start + eb->len);
offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1); offset = (start_offset + start) & ((unsigned long)PAGE_CACHE_SIZE - 1);
if (i == 0)
offset += start_offset;
while(len > 0) { while(len > 0) {
page = extent_buffer_page(eb, i); page = extent_buffer_page(eb, i);
...@@ -2514,9 +2513,7 @@ void write_extent_buffer(struct extent_buffer *eb, const void *srcv, ...@@ -2514,9 +2513,7 @@ void write_extent_buffer(struct extent_buffer *eb, const void *srcv,
WARN_ON(start > eb->len); WARN_ON(start > eb->len);
WARN_ON(start + len > eb->start + eb->len); WARN_ON(start + len > eb->start + eb->len);
offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1); offset = (start_offset + start) & ((unsigned long)PAGE_CACHE_SIZE - 1);
if (i == 0)
offset += start_offset;
while(len > 0) { while(len > 0) {
page = extent_buffer_page(eb, i); page = extent_buffer_page(eb, i);
...@@ -2548,9 +2545,7 @@ void memset_extent_buffer(struct extent_buffer *eb, char c, ...@@ -2548,9 +2545,7 @@ void memset_extent_buffer(struct extent_buffer *eb, char c,
WARN_ON(start > eb->len); WARN_ON(start > eb->len);
WARN_ON(start + len > eb->start + eb->len); WARN_ON(start + len > eb->start + eb->len);
offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1); offset = (start_offset + start) & ((unsigned long)PAGE_CACHE_SIZE - 1);
if (i == 0)
offset += start_offset;
while(len > 0) { while(len > 0) {
page = extent_buffer_page(eb, i); page = extent_buffer_page(eb, i);
...@@ -2582,9 +2577,8 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src, ...@@ -2582,9 +2577,8 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
WARN_ON(src->len != dst_len); WARN_ON(src->len != dst_len);
offset = dst_offset & ((unsigned long)PAGE_CACHE_SIZE - 1); offset = (start_offset + dst_offset) &
if (i == 0) ((unsigned long)PAGE_CACHE_SIZE - 1);
offset += start_offset;
while(len > 0) { while(len > 0) {
page = extent_buffer_page(dst, i); page = extent_buffer_page(dst, i);
...@@ -2664,19 +2658,14 @@ void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, ...@@ -2664,19 +2658,14 @@ void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
} }
while(len > 0) { while(len > 0) {
dst_off_in_page = dst_offset & dst_off_in_page = (start_offset + dst_offset) &
((unsigned long)PAGE_CACHE_SIZE - 1); ((unsigned long)PAGE_CACHE_SIZE - 1);
src_off_in_page = src_offset & src_off_in_page = (start_offset + src_offset) &
((unsigned long)PAGE_CACHE_SIZE - 1); ((unsigned long)PAGE_CACHE_SIZE - 1);
dst_i = (start_offset + dst_offset) >> PAGE_CACHE_SHIFT; dst_i = (start_offset + dst_offset) >> PAGE_CACHE_SHIFT;
src_i = (start_offset + src_offset) >> PAGE_CACHE_SHIFT; src_i = (start_offset + src_offset) >> PAGE_CACHE_SHIFT;
if (src_i == 0)
src_off_in_page += start_offset;
if (dst_i == 0)
dst_off_in_page += start_offset;
cur = min(len, (unsigned long)(PAGE_CACHE_SIZE - cur = min(len, (unsigned long)(PAGE_CACHE_SIZE -
src_off_in_page)); src_off_in_page));
cur = min_t(unsigned long, cur, cur = min_t(unsigned long, cur,
...@@ -2723,14 +2712,10 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, ...@@ -2723,14 +2712,10 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
dst_i = (start_offset + dst_end) >> PAGE_CACHE_SHIFT; dst_i = (start_offset + dst_end) >> PAGE_CACHE_SHIFT;
src_i = (start_offset + src_end) >> PAGE_CACHE_SHIFT; src_i = (start_offset + src_end) >> PAGE_CACHE_SHIFT;
dst_off_in_page = dst_end & dst_off_in_page = (start_offset + dst_end) &
((unsigned long)PAGE_CACHE_SIZE - 1); ((unsigned long)PAGE_CACHE_SIZE - 1);
src_off_in_page = src_end & src_off_in_page = (start_offset + src_end) &
((unsigned long)PAGE_CACHE_SIZE - 1); ((unsigned long)PAGE_CACHE_SIZE - 1);
if (src_i == 0)
src_off_in_page += start_offset;
if (dst_i == 0)
dst_off_in_page += start_offset;
cur = min_t(unsigned long, len, src_off_in_page + 1); cur = min_t(unsigned long, len, src_off_in_page + 1);
cur = min(cur, dst_off_in_page + 1); cur = min(cur, dst_off_in_page + 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment