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

Commit 452c75c3 authored by Chandra Seetharaman's avatar Chandra Seetharaman Committed by Chris Mason
Browse files

Btrfs: Simplify the logic in alloc_extent_buffer() for existing extent buffer case



alloc_extent_buffer() uses radix_tree_lookup() when radix_tree_insert()
fails with EEXIST. That part of the code is very similar to the code in
find_extent_buffer(). This patch replaces radix_tree_lookup() and
surrounding code in alloc_extent_buffer() with find_extent_buffer().

Note that radix_tree_lookup() does not need to be protected by
tree->buffer_lock. It is protected by eb->refs.

While at it, this patch
  - changes the other usage of radix_tree_lookup() in alloc_extent_buffer()
    with find_extent_buffer() to reduce redundancy.
  - removes the unused argument 'len' to find_extent_buffer().

Signed-Off-by: default avatarChandra Seetharaman <sekharan@us.ibm.com>
Reviewed-by: default avatarZach Brown <zab@redhat.com>

Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
parent 7f4ca37c
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -1104,8 +1104,7 @@ struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
{
	struct inode *btree_inode = root->fs_info->btree_inode;
	struct extent_buffer *eb;
	eb = find_extent_buffer(&BTRFS_I(btree_inode)->io_tree,
				bytenr, blocksize);
	eb = find_extent_buffer(&BTRFS_I(btree_inode)->io_tree, bytenr);
	return eb;
}

+26 −37
Original line number Diff line number Diff line
@@ -4486,6 +4486,23 @@ static void mark_extent_buffer_accessed(struct extent_buffer *eb)
	}
}

struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree,
					 		u64 start)
{
	struct extent_buffer *eb;

	rcu_read_lock();
	eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT);
	if (eb && atomic_inc_not_zero(&eb->refs)) {
		rcu_read_unlock();
		mark_extent_buffer_accessed(eb);
		return eb;
	}
	rcu_read_unlock();

	return NULL;
}

struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
					  u64 start, unsigned long len)
{
@@ -4499,14 +4516,10 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
	int uptodate = 1;
	int ret;

	rcu_read_lock();
	eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT);
	if (eb && atomic_inc_not_zero(&eb->refs)) {
		rcu_read_unlock();
		mark_extent_buffer_accessed(eb);

	eb = find_extent_buffer(tree, start);
	if (eb)
		return eb;
	}
	rcu_read_unlock();

	eb = __alloc_extent_buffer(tree, start, len, GFP_NOFS);
	if (!eb)
@@ -4565,24 +4578,17 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,

	spin_lock(&tree->buffer_lock);
	ret = radix_tree_insert(&tree->buffer, start >> PAGE_CACHE_SHIFT, eb);
	if (ret == -EEXIST) {
		exists = radix_tree_lookup(&tree->buffer,
						start >> PAGE_CACHE_SHIFT);
		if (!atomic_inc_not_zero(&exists->refs)) {
			spin_unlock(&tree->buffer_lock);
			radix_tree_preload_end();
			exists = NULL;
			goto again;
		}
	spin_unlock(&tree->buffer_lock);
	radix_tree_preload_end();
		mark_extent_buffer_accessed(exists);
	if (ret == -EEXIST) {
		exists = find_extent_buffer(tree, start);
		if (exists)
			goto free_eb;
		else
			goto again;
	}
	/* add one reference for the tree */
	check_buffer_tree_ref(eb);
	spin_unlock(&tree->buffer_lock);
	radix_tree_preload_end();

	/*
	 * there is a race where release page may have
@@ -4613,23 +4619,6 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
	return exists;
}

struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree,
					 u64 start, unsigned long len)
{
	struct extent_buffer *eb;

	rcu_read_lock();
	eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT);
	if (eb && atomic_inc_not_zero(&eb->refs)) {
		rcu_read_unlock();
		mark_extent_buffer_accessed(eb);
		return eb;
	}
	rcu_read_unlock();

	return NULL;
}

static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head)
{
	struct extent_buffer *eb =
+1 −1
Original line number Diff line number Diff line
@@ -271,7 +271,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
struct extent_buffer *alloc_dummy_extent_buffer(u64 start, unsigned long len);
struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src);
struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree,
					 u64 start, unsigned long len);
					 u64 start);
void free_extent_buffer(struct extent_buffer *eb);
void free_extent_buffer_stale(struct extent_buffer *eb);
#define WAIT_NONE	0