aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
authorChandra Seetharaman <sekharan@us.ibm.com>2013-10-07 11:45:25 -0400
committerChris Mason <chris.mason@fusionio.com>2013-11-11 21:59:11 -0500
commit452c75c3d2187089f6e846710e6ea7883bf30f8a (patch)
tree0747512f55c254c1102fd878c9fca20c0138ea33 /fs/btrfs/extent_io.c
parent7f4ca37c486733da008778a1f4058fbc194a4fdd (diff)
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: Chandra Seetharaman <sekharan@us.ibm.com> Reviewed-by: Zach Brown <zab@redhat.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c63
1 files changed, 26 insertions, 37 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index c10291cc4fd1..5439f24ab06b 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -4486,6 +4486,23 @@ static void mark_extent_buffer_accessed(struct extent_buffer *eb)
4486 } 4486 }
4487} 4487}
4488 4488
4489struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree,
4490 u64 start)
4491{
4492 struct extent_buffer *eb;
4493
4494 rcu_read_lock();
4495 eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT);
4496 if (eb && atomic_inc_not_zero(&eb->refs)) {
4497 rcu_read_unlock();
4498 mark_extent_buffer_accessed(eb);
4499 return eb;
4500 }
4501 rcu_read_unlock();
4502
4503 return NULL;
4504}
4505
4489struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, 4506struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
4490 u64 start, unsigned long len) 4507 u64 start, unsigned long len)
4491{ 4508{
@@ -4499,14 +4516,10 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
4499 int uptodate = 1; 4516 int uptodate = 1;
4500 int ret; 4517 int ret;
4501 4518
4502 rcu_read_lock(); 4519
4503 eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); 4520 eb = find_extent_buffer(tree, start);
4504 if (eb && atomic_inc_not_zero(&eb->refs)) { 4521 if (eb)
4505 rcu_read_unlock();
4506 mark_extent_buffer_accessed(eb);
4507 return eb; 4522 return eb;
4508 }
4509 rcu_read_unlock();
4510 4523
4511 eb = __alloc_extent_buffer(tree, start, len, GFP_NOFS); 4524 eb = __alloc_extent_buffer(tree, start, len, GFP_NOFS);
4512 if (!eb) 4525 if (!eb)
@@ -4565,24 +4578,17 @@ again:
4565 4578
4566 spin_lock(&tree->buffer_lock); 4579 spin_lock(&tree->buffer_lock);
4567 ret = radix_tree_insert(&tree->buffer, start >> PAGE_CACHE_SHIFT, eb); 4580 ret = radix_tree_insert(&tree->buffer, start >> PAGE_CACHE_SHIFT, eb);
4581 spin_unlock(&tree->buffer_lock);
4582 radix_tree_preload_end();
4568 if (ret == -EEXIST) { 4583 if (ret == -EEXIST) {
4569 exists = radix_tree_lookup(&tree->buffer, 4584 exists = find_extent_buffer(tree, start);
4570 start >> PAGE_CACHE_SHIFT); 4585 if (exists)
4571 if (!atomic_inc_not_zero(&exists->refs)) { 4586 goto free_eb;
4572 spin_unlock(&tree->buffer_lock); 4587 else
4573 radix_tree_preload_end();
4574 exists = NULL;
4575 goto again; 4588 goto again;
4576 }
4577 spin_unlock(&tree->buffer_lock);
4578 radix_tree_preload_end();
4579 mark_extent_buffer_accessed(exists);
4580 goto free_eb;
4581 } 4589 }
4582 /* add one reference for the tree */ 4590 /* add one reference for the tree */
4583 check_buffer_tree_ref(eb); 4591 check_buffer_tree_ref(eb);
4584 spin_unlock(&tree->buffer_lock);
4585 radix_tree_preload_end();
4586 4592
4587 /* 4593 /*
4588 * there is a race where release page may have 4594 * there is a race where release page may have
@@ -4613,23 +4619,6 @@ free_eb:
4613 return exists; 4619 return exists;
4614} 4620}
4615 4621
4616struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree,
4617 u64 start, unsigned long len)
4618{
4619 struct extent_buffer *eb;
4620
4621 rcu_read_lock();
4622 eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT);
4623 if (eb && atomic_inc_not_zero(&eb->refs)) {
4624 rcu_read_unlock();
4625 mark_extent_buffer_accessed(eb);
4626 return eb;
4627 }
4628 rcu_read_unlock();
4629
4630 return NULL;
4631}
4632
4633static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head) 4622static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head)
4634{ 4623{
4635 struct extent_buffer *eb = 4624 struct extent_buffer *eb =