mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-18 10:56:14 +00:00
Btrfs: CPU usage optimizations in push and the extent_map code
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
59d169e2b3
commit
3685f79165
@ -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
|
|||||||
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
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user