Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 308d9800 authored by Filipe Manana's avatar Filipe Manana Committed by Chris Mason
Browse files

Btrfs: cache extent states in defrag code path



When locking file ranges in the inode's io_tree, cache the first
extent state that belongs to the target range, so that when unlocking
the range we don't need to search in the io_tree again, reducing cpu
time and making and therefore holding the io_tree's lock for a shorter
period.

Signed-off-by: default avatarFilipe David Borba Manana <fdmanana@gmail.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 3bbb24b2
Loading
Loading
Loading
Loading
+9 −4
Original line number Original line Diff line number Diff line
@@ -986,10 +986,13 @@ static struct extent_map *defrag_lookup_extent(struct inode *inode, u64 start)
	read_unlock(&em_tree->lock);
	read_unlock(&em_tree->lock);


	if (!em) {
	if (!em) {
		struct extent_state *cached = NULL;
		u64 end = start + len - 1;

		/* get the big lock and read metadata off disk */
		/* get the big lock and read metadata off disk */
		lock_extent(io_tree, start, start + len - 1);
		lock_extent_bits(io_tree, start, end, 0, &cached);
		em = btrfs_get_extent(inode, NULL, 0, start, len, 0);
		em = btrfs_get_extent(inode, NULL, 0, start, len, 0);
		unlock_extent(io_tree, start, start + len - 1);
		unlock_extent_cached(io_tree, start, end, &cached, GFP_NOFS);


		if (IS_ERR(em))
		if (IS_ERR(em))
			return NULL;
			return NULL;
@@ -1128,10 +1131,12 @@ static int cluster_pages_for_defrag(struct inode *inode,
		page_start = page_offset(page);
		page_start = page_offset(page);
		page_end = page_start + PAGE_CACHE_SIZE - 1;
		page_end = page_start + PAGE_CACHE_SIZE - 1;
		while (1) {
		while (1) {
			lock_extent(tree, page_start, page_end);
			lock_extent_bits(tree, page_start, page_end,
					 0, &cached_state);
			ordered = btrfs_lookup_ordered_extent(inode,
			ordered = btrfs_lookup_ordered_extent(inode,
							      page_start);
							      page_start);
			unlock_extent(tree, page_start, page_end);
			unlock_extent_cached(tree, page_start, page_end,
					     &cached_state, GFP_NOFS);
			if (!ordered)
			if (!ordered)
				break;
				break;