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

Btrfs: CPU usage optimizations in push and the extent_map code

parent 59d169e2
Loading
Loading
Loading
Loading
+24 −20
Original line number Diff line number Diff line
@@ -1588,6 +1588,11 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
	if (!path->nodes[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],
			       slot - 1), root->leafsize);
	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);
		return 1;
	}

	free_space = btrfs_leaf_free_space(root, left);
	if (free_space < data_size + sizeof(struct btrfs_item)) {
		free_extent_buffer(left);
		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++) {
		item = btrfs_item_nr(right, i);
		if (!right->map_token) {
@@ -1772,12 +1772,13 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
	struct btrfs_disk_key disk_key;

	/* 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) {
		wret = push_leaf_right(trans, root, path, data_size);
		if (wret < 0) {
			return wret;
		}
		if (wret) {
		wret = push_leaf_right(trans, root, path, data_size);
			wret = push_leaf_left(trans, root, path, data_size);
			if (wret < 0)
				return wret;
		}
@@ -1788,6 +1789,9 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
		    sizeof(struct btrfs_item) + data_size) {
			return 0;
		}
	} else {
		l = path->nodes[0];
	}

	if (!path->nodes[1]) {
		ret = insert_new_root(trans, root, path, 1);
@@ -2388,13 +2392,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_left(trans, root, path, 1);
			wret = push_leaf_right(trans, root, path, 1);
			if (wret < 0 && wret != -ENOSPC)
				ret = wret;

			if (path->nodes[0] == 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)
					ret = wret;
			}
+15 −30
Original line number Diff line number Diff line
@@ -1986,12 +1986,15 @@ static inline struct page *extent_buffer_page(struct extent_buffer *eb,
					      unsigned long i)
{
	struct page *p;
	struct address_space *mapping;

	if (i == 0)
		return eb->first_page;
	i += eb->start >> PAGE_CACHE_SHIFT;
	p = find_get_page(eb->first_page->mapping, i);
	page_cache_release(p);
	mapping = eb->first_page->mapping;
	read_lock_irq(&mapping->tree_lock);
	p = radix_tree_lookup(&mapping->page_tree, i);
	read_unlock_irq(&mapping->tree_lock);
	return p;
}

@@ -2365,9 +2368,7 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv,
	WARN_ON(start > eb->len);
	WARN_ON(start + len > eb->start + eb->len);

	offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1);
	if (i == 0)
		offset += start_offset;
	offset = (start_offset + start) & ((unsigned long)PAGE_CACHE_SIZE - 1);

	while(len > 0) {
		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 + len > eb->start + eb->len);

	offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1);
	if (i == 0)
		offset += start_offset;
	offset = (start_offset + start) & ((unsigned long)PAGE_CACHE_SIZE - 1);

	while(len > 0) {
		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 + len > eb->start + eb->len);

	offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1);
	if (i == 0)
		offset += start_offset;
	offset = (start_offset + start) & ((unsigned long)PAGE_CACHE_SIZE - 1);

	while(len > 0) {
		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 + len > eb->start + eb->len);

	offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1);
	if (i == 0)
		offset += start_offset;
	offset = (start_offset + start) & ((unsigned long)PAGE_CACHE_SIZE - 1);

	while(len > 0) {
		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);

	offset = dst_offset & ((unsigned long)PAGE_CACHE_SIZE - 1);
	if (i == 0)
		offset += start_offset;
	offset = (start_offset + dst_offset) &
		((unsigned long)PAGE_CACHE_SIZE - 1);

	while(len > 0) {
		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) {
		dst_off_in_page = dst_offset &
		dst_off_in_page = (start_offset + dst_offset) &
			((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);

		dst_i = (start_offset + dst_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 -
					       src_off_in_page));
		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;
		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);
		src_off_in_page = src_end &
		src_off_in_page = (start_offset + src_end) &
			((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(cur, dst_off_in_page + 1);