aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-09-02 15:04:12 -0400
committerChris Mason <chris.mason@oracle.com>2009-09-11 13:31:06 -0400
commit2c64c53d8d30d43d0670482503a3914dfd3d6d46 (patch)
treecfe7bfa8f5dc4078f8c995f305229622e25572b1
parent1edbb734b4e010974c41d2859d22a43d04f5f1cf (diff)
Btrfs: cache values for locking extents
Many of the btrfs extent state tree users follow the same pattern. They lock an extent range in the tree, do some operation and then unlock. This translates to at least 2 rbtree searches, and maybe more if they are doing operations on the extent state tree. A locked extent in the tree isn't going to be merged or changed, and so we can safely return the extent state structure as a cached handle. This changes set_extent_bit to give back a cached handle, and also changes both set_extent_bit and clear_extent_bit to use the cached handle if it is available. Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/extent_io.c125
-rw-r--r--fs/btrfs/extent_io.h5
-rw-r--r--fs/btrfs/inode.c6
3 files changed, 100 insertions, 36 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 7c70613eb72c..c7a5e860fe21 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -471,10 +471,14 @@ static int clear_state_bit(struct extent_io_tree *tree,
471 * bits were already set, or zero if none of the bits were already set. 471 * bits were already set, or zero if none of the bits were already set.
472 */ 472 */
473int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, 473int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
474 int bits, int wake, int delete, gfp_t mask) 474 int bits, int wake, int delete,
475 struct extent_state **cached_state,
476 gfp_t mask)
475{ 477{
476 struct extent_state *state; 478 struct extent_state *state;
479 struct extent_state *cached;
477 struct extent_state *prealloc = NULL; 480 struct extent_state *prealloc = NULL;
481 struct rb_node *next_node;
478 struct rb_node *node; 482 struct rb_node *node;
479 u64 last_end; 483 u64 last_end;
480 int err; 484 int err;
@@ -488,6 +492,17 @@ again:
488 } 492 }
489 493
490 spin_lock(&tree->lock); 494 spin_lock(&tree->lock);
495 if (cached_state) {
496 cached = *cached_state;
497 *cached_state = NULL;
498 if (cached->tree && cached->start == start) {
499 atomic_dec(&cached->refs);
500 state = cached;
501 last_end = state->end;
502 goto found;
503 }
504 free_extent_state(cached);
505 }
491 /* 506 /*
492 * this search will find the extents that end after 507 * this search will find the extents that end after
493 * our range starts 508 * our range starts
@@ -496,6 +511,7 @@ again:
496 if (!node) 511 if (!node)
497 goto out; 512 goto out;
498 state = rb_entry(node, struct extent_state, rb_node); 513 state = rb_entry(node, struct extent_state, rb_node);
514hit_next:
499 if (state->start > end) 515 if (state->start > end)
500 goto out; 516 goto out;
501 WARN_ON(state->end < start); 517 WARN_ON(state->end < start);
@@ -555,11 +571,21 @@ again:
555 prealloc = NULL; 571 prealloc = NULL;
556 goto out; 572 goto out;
557 } 573 }
558 574found:
575 if (state->end < end && prealloc && !need_resched())
576 next_node = rb_next(&state->rb_node);
577 else
578 next_node = NULL;
559 set |= clear_state_bit(tree, state, bits, wake, delete); 579 set |= clear_state_bit(tree, state, bits, wake, delete);
560 if (last_end == (u64)-1) 580 if (last_end == (u64)-1)
561 goto out; 581 goto out;
562 start = last_end + 1; 582 start = last_end + 1;
583 if (start <= end && next_node) {
584 state = rb_entry(next_node, struct extent_state,
585 rb_node);
586 if (state->start == start)
587 goto hit_next;
588 }
563 goto search_again; 589 goto search_again;
564 590
565out: 591out:
@@ -653,6 +679,17 @@ static void set_state_bits(struct extent_io_tree *tree,
653 state->state |= bits; 679 state->state |= bits;
654} 680}
655 681
682static void cache_state(struct extent_state *state,
683 struct extent_state **cached_ptr)
684{
685 if (cached_ptr && !(*cached_ptr)) {
686 if (state->state & (EXTENT_IOBITS | EXTENT_BOUNDARY)) {
687 *cached_ptr = state;
688 atomic_inc(&state->refs);
689 }
690 }
691}
692
656/* 693/*
657 * set some bits on a range in the tree. This may require allocations or 694 * set some bits on a range in the tree. This may require allocations or
658 * sleeping, so the gfp mask is used to indicate what is allowed. 695 * sleeping, so the gfp mask is used to indicate what is allowed.
@@ -666,6 +703,7 @@ static void set_state_bits(struct extent_io_tree *tree,
666 703
667static int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, 704static int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
668 int bits, int exclusive_bits, u64 *failed_start, 705 int bits, int exclusive_bits, u64 *failed_start,
706 struct extent_state **cached_state,
669 gfp_t mask) 707 gfp_t mask)
670{ 708{
671 struct extent_state *state; 709 struct extent_state *state;
@@ -712,6 +750,7 @@ hit_next:
712 goto out; 750 goto out;
713 } 751 }
714 set_state_bits(tree, state, bits); 752 set_state_bits(tree, state, bits);
753 cache_state(state, cached_state);
715 merge_state(tree, state); 754 merge_state(tree, state);
716 if (last_end == (u64)-1) 755 if (last_end == (u64)-1)
717 goto out; 756 goto out;
@@ -758,6 +797,7 @@ hit_next:
758 goto out; 797 goto out;
759 if (state->end <= end) { 798 if (state->end <= end) {
760 set_state_bits(tree, state, bits); 799 set_state_bits(tree, state, bits);
800 cache_state(state, cached_state);
761 merge_state(tree, state); 801 merge_state(tree, state);
762 if (last_end == (u64)-1) 802 if (last_end == (u64)-1)
763 goto out; 803 goto out;
@@ -782,6 +822,7 @@ hit_next:
782 this_end = last_start - 1; 822 this_end = last_start - 1;
783 err = insert_state(tree, prealloc, start, this_end, 823 err = insert_state(tree, prealloc, start, this_end,
784 bits); 824 bits);
825 cache_state(prealloc, cached_state);
785 prealloc = NULL; 826 prealloc = NULL;
786 BUG_ON(err == -EEXIST); 827 BUG_ON(err == -EEXIST);
787 if (err) 828 if (err)
@@ -805,6 +846,7 @@ hit_next:
805 BUG_ON(err == -EEXIST); 846 BUG_ON(err == -EEXIST);
806 847
807 set_state_bits(tree, prealloc, bits); 848 set_state_bits(tree, prealloc, bits);
849 cache_state(prealloc, cached_state);
808 merge_state(tree, prealloc); 850 merge_state(tree, prealloc);
809 prealloc = NULL; 851 prealloc = NULL;
810 goto out; 852 goto out;
@@ -833,26 +875,27 @@ int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
833 gfp_t mask) 875 gfp_t mask)
834{ 876{
835 return set_extent_bit(tree, start, end, EXTENT_DIRTY, 0, NULL, 877 return set_extent_bit(tree, start, end, EXTENT_DIRTY, 0, NULL,
836 mask); 878 NULL, mask);
837} 879}
838 880
839int set_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end, 881int set_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end,
840 gfp_t mask) 882 gfp_t mask)
841{ 883{
842 return set_extent_bit(tree, start, end, EXTENT_ORDERED, 0, NULL, mask); 884 return set_extent_bit(tree, start, end, EXTENT_ORDERED, 0, NULL, NULL,
885 mask);
843} 886}
844 887
845int set_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, 888int set_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
846 int bits, gfp_t mask) 889 int bits, gfp_t mask)
847{ 890{
848 return set_extent_bit(tree, start, end, bits, 0, NULL, 891 return set_extent_bit(tree, start, end, bits, 0, NULL,
849 mask); 892 NULL, mask);
850} 893}
851 894
852int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, 895int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
853 int bits, gfp_t mask) 896 int bits, gfp_t mask)
854{ 897{
855 return clear_extent_bit(tree, start, end, bits, 0, 0, mask); 898 return clear_extent_bit(tree, start, end, bits, 0, 0, NULL, mask);
856} 899}
857 900
858int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, 901int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
@@ -860,46