aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-07-22 11:18:07 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:05 -0400
commit6af118ce51b52ceda357c671550c79628b9c4a65 (patch)
treeb03fb64eb4567d1d1320a43f5d2142bc65193c18
parent4a09675279674041862d2210635b0cc1f60be28e (diff)
Btrfs: Index extent buffers in an rbtree
Before, extent buffers were a temporary object, meant to map a number of pages at once and collect operations on them. But, a few extra fields have crept in, and they are also the best place to store a per-tree block lock field as well. This commit puts the extent buffers into an rbtree, and ensures a single extent buffer for each tree block. Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/disk-io.c26
-rw-r--r--fs/btrfs/extent_io.c309
-rw-r--r--fs/btrfs/extent_io.h11
-rw-r--r--fs/btrfs/inode.c3
4 files changed, 129 insertions, 220 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 99bb385c2982..86e84a8579e3 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -381,7 +381,6 @@ int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
381 381
382 end = min_t(u64, eb->len, PAGE_CACHE_SIZE); 382 end = min_t(u64, eb->len, PAGE_CACHE_SIZE);
383 end = eb->start + end - 1; 383 end = eb->start + end - 1;
384 release_extent_buffer_tail_pages(eb);
385err: 384err:
386 free_extent_buffer(eb); 385 free_extent_buffer(eb);
387out: 386out:
@@ -563,21 +562,21 @@ static int btree_releasepage(struct page *page, gfp_t gfp_flags)
563 struct extent_map_tree *map; 562 struct extent_map_tree *map;
564 int ret; 563 int ret;
565 564
566 if (page_count(page) > 3) {
567 /* once for page->private, once for the caller, once
568 * once for the page cache
569 */
570 return 0;
571 }
572 tree = &BTRFS_I(page->mapping->host)->io_tree; 565 tree = &BTRFS_I(page->mapping->host)->io_tree;
573 map = &BTRFS_I(page->mapping->host)->extent_tree; 566 map = &BTRFS_I(page->mapping->host)->extent_tree;
567
574 ret = try_release_extent_state(map, tree, page, gfp_flags); 568 ret = try_release_extent_state(map, tree, page, gfp_flags);
569 if (!ret) {
570 return 0;
571 }
572
573 ret = try_release_extent_buffer(tree, page);
575 if (ret == 1) { 574 if (ret == 1) {
576 invalidate_extent_lru(tree, page_offset(page), PAGE_CACHE_SIZE);
577 ClearPagePrivate(page); 575 ClearPagePrivate(page);
578 set_page_private(page, 0); 576 set_page_private(page, 0);
579 page_cache_release(page); 577 page_cache_release(page);
580 } 578 }
579
581 return ret; 580 return ret;
582} 581}
583 582
@@ -588,7 +587,8 @@ static void btree_invalidatepage(struct page *page, unsigned long offset)
588 extent_invalidatepage(tree, page, offset); 587 extent_invalidatepage(tree, page, offset);
589 btree_releasepage(page, GFP_NOFS); 588 btree_releasepage(page, GFP_NOFS);
590 if (PagePrivate(page)) { 589 if (PagePrivate(page)) {
591 invalidate_extent_lru(tree, page_offset(page), PAGE_CACHE_SIZE); 590 printk("warning page private not zero on page %Lu\n",
591 page_offset(page));
592 ClearPagePrivate(page); 592 ClearPagePrivate(page);
593 set_page_private(page, 0); 593 set_page_private(page, 0);
594 page_cache_release(page); 594 page_cache_release(page);
@@ -1456,7 +1456,6 @@ fail_tree_root:
1456 free_extent_buffer(tree_root->node); 1456 free_extent_buffer(tree_root->node);
1457fail_sys_array: 1457fail_sys_array:
1458fail_sb_buffer: 1458fail_sb_buffer:
1459 extent_io_tree_empty_lru(&BTRFS_I(fs_info->btree_inode)->io_tree);
1460 btrfs_stop_workers(&fs_info->fixup_workers); 1459 btrfs_stop_workers(&fs_info->fixup_workers);
1461 btrfs_stop_workers(&fs_info->workers); 1460 btrfs_stop_workers(&fs_info->workers);
1462 btrfs_stop_workers(&fs_info->endio_workers); 1461 btrfs_stop_workers(&fs_info->endio_workers);
@@ -1705,13 +1704,6 @@ int close_ctree(struct btrfs_root *root)
1705 1704
1706 filemap_write_and_wait(fs_info->btree_inode->i_mapping); 1705 filemap_write_and_wait(fs_info->btree_inode->i_mapping);
1707 1706
1708 extent_io_tree_empty_lru(&fs_info->free_space_cache);
1709 extent_io_tree_empty_lru(&fs_info->block_group_cache);
1710 extent_io_tree_empty_lru(&fs_info->pinned_extents);
1711 extent_io_tree_empty_lru(&fs_info->pending_del);
1712 extent_io_tree_empty_lru(&fs_info->extent_ins);
1713 extent_io_tree_empty_lru(&BTRFS_I(fs_info->btree_inode)->io_tree);
1714
1715 truncate_inode_pages(fs_info->btree_inode->i_mapping, 0); 1707 truncate_inode_pages(fs_info->btree_inode->i_mapping, 0);
1716 1708
1717 btrfs_stop_workers(&fs_info->fixup_workers); 1709 btrfs_stop_workers(&fs_info->fixup_workers);
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index d4a63ae7ed1b..32bb4ed3723d 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -91,29 +91,16 @@ void extent_io_tree_init(struct extent_io_tree *tree,
91 struct address_space *mapping, gfp_t mask) 91 struct address_space *mapping, gfp_t mask)
92{ 92{
93 tree->state.rb_node = NULL; 93 tree->state.rb_node = NULL;
94 tree->buffer.rb_node = NULL;
94 tree->ops = NULL; 95 tree->ops = NULL;
95 tree->dirty_bytes = 0; 96 tree->dirty_bytes = 0;
96 spin_lock_init(&tree->lock); 97 spin_lock_init(&tree->lock);
97 spin_lock_init(&tree->lru_lock); 98 spin_lock_init(&tree->buffer_lock);
98 tree->mapping = mapping; 99 tree->mapping = mapping;
99 INIT_LIST_HEAD(&tree->buffer_lru);
100 tree->lru_size = 0;
101 tree->last = NULL; 100 tree->last = NULL;
102} 101}
103EXPORT_SYMBOL(extent_io_tree_init); 102EXPORT_SYMBOL(extent_io_tree_init);
104 103
105void extent_io_tree_empty_lru(struct extent_io_tree *tree)
106{
107 struct extent_buffer *eb;
108 while(!list_empty(&tree->buffer_lru)) {
109 eb = list_entry(tree->buffer_lru.next, struct extent_buffer,
110 lru);
111 list_del_init(&eb->lru);
112 free_extent_buffer(eb);
113 }
114}
115EXPORT_SYMBOL(extent_io_tree_empty_lru);
116
117struct extent_state *alloc_extent_state(gfp_t mask) 104struct extent_state *alloc_extent_state(gfp_t mask)
118{ 105{
119 struct extent_state *state; 106 struct extent_state *state;
@@ -245,6 +232,50 @@ static inline struct rb_node *tree_search(struct extent_io_tree *tree,
245 return ret; 232 return ret;
246} 233}
247 234
235static struct extent_buffer *buffer_tree_insert(struct extent_io_tree *tree,
236 u64 offset, struct rb_node *node)
237{
238 struct rb_root *root = &tree->buffer;
239 struct rb_node ** p = &root->rb_node;
240 struct rb_node * parent = NULL;
241 struct extent_buffer *eb;
242
243 while(*p) {
244 parent = *p;
245 eb = rb_entry(parent, struct extent_buffer, rb_node);
246
247 if (offset < eb->start)
248 p = &(*p)->rb_left;
249 else if (offset > eb->start)
250 p = &(*p)->rb_right;
251 else
252 return eb;
253 }
254
255 rb_link_node(node, parent, p);
256 rb_insert_color(node, root);
257 return NULL;
258}
259
260static struct extent_buffer *buffer_search(struct extent_io_tree *tree,
261 u64 offset)
262{
263 struct rb_root *root = &tree->buffer;
264 struct rb_node * n = root->rb_node;
265 struct extent_buffer *eb;
266
267 while(n) {
268 eb = rb_entry(n, struct extent_buffer, rb_node);
269 if (offset < eb->start)
270 n = n->rb_left;
271 else if (offset > eb->start)
272 n = n->rb_right;
273 else
274 return eb;
275 }
276 return NULL;
277}
278
248/* 279/*
249 * utility function to look for merge candidates inside a given range. 280 * utility function to look for merge candidates inside a given range.
250 * Any extents with matching state are merged together into a single 281 * Any extents with matching state are merged together into a single
@@ -1817,9 +1848,8 @@ void set_page_extent_mapped(struct page *page)
1817{ 1848{
1818 if (!PagePrivate(page)) { 1849 if (!PagePrivate(page)) {
1819 SetPagePrivate(page); 1850 SetPagePrivate(page);
1820 WARN_ON(!page->mapping->a_ops->invalidatepage);
1821 set_page_private(page, EXTENT_PAGE_PRIVATE);
1822 page_cache_get(page); 1851 page_cache_get(page);
1852 set_page_private(page, EXTENT_PAGE_PRIVATE);
1823 } 1853 }
1824} 1854}
1825 1855
@@ -2627,51 +2657,6 @@ out:
2627 return sector; 2657 return sector;
2628} 2658}
2629 2659
2630static int add_lru(struct extent_io_tree *tree, struct extent_buffer *eb)
2631{
2632 if (list_empty(&eb->lru)) {
2633 extent_buffer_get(eb);
2634 list_add(&eb->lru, &tree->buffer_lru);
2635 tree->lru_size++;
2636 if (tree->lru_size >= BUFFER_LRU_MAX) {
2637 struct extent_buffer *rm;
2638 rm = list_entry(tree->buffer_lru.prev,
2639 struct extent_buffer, lru);
2640 tree->lru_size--;
2641 list_del_init(&rm->lru);
2642 free_extent_buffer(rm);
2643 }
2644 } else
2645 list_move(&eb->lru, &tree->buffer_lru);
2646 return 0;
2647}
2648static struct extent_buffer *find_lru(struct extent_io_tree *tree,
2649 u64 start, unsigned long len)
2650{
2651 struct list_head *lru = &tree->buffer_lru;
2652 struct list_head *cur = lru->next;
2653 struct extent_buffer *eb;
2654
2655 if (list_empty(lru))
2656 return NULL;
2657
2658 do {
2659 eb = list_entry(cur, struct extent_buffer, lru);
2660 if (eb->start == start && eb->len == len) {
2661 extent_buffer_get(eb);
2662 return eb;
2663 }
2664 cur = cur->next;
2665 } while (cur != lru);
2666 return NULL;
2667}
2668
2669static inline unsigned long num_extent_pages(u64 start, u64 len)
2670{
2671 return ((start + len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) -
2672 (start >> PAGE_CACHE_SHIFT);
2673}
2674
2675static inline struct page *extent_buffer_page(struct extent_buffer *eb, 2660static inline struct page *extent_buffer_page(struct extent_buffer *eb,
2676 unsigned long i) 2661 unsigned long i)
2677{ 2662{
@@ -2688,44 +2673,10 @@ static inline struct page *extent_buffer_page(struct extent_buffer *eb,
2688 return p; 2673 return p;
2689} 2674}
2690 2675
2691int release_extent_buffer_tail_pages(struct extent_buffer *eb) 2676static inline unsigned long num_extent_pages(u64 start, u64 len)
2692{
2693 unsigned long num_pages = num_extent_pages(eb->start, eb->len);
2694 struct page *page;
2695 unsigned long i;
2696
2697 if (num_pages == 1)
2698 return 0;
2699 for (i = 1; i < num_pages; i++) {
2700 page = extent_buffer_page(eb, i);
2701 page_cache_release(page);
2702 }
2703 return 0;
2704}
2705
2706
2707int invalidate_extent_lru(struct extent_io_tree *tree, u64 start,
2708 unsigned long len)
2709{ 2677{
2710 struct list_head *lru = &tree->buffer_lru; 2678 return ((start + len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) -
2711 struct list_head *cur = lru->next; 2679 (start >> PAGE_CACHE_SHIFT);
2712 struct extent_buffer *eb;
2713 int found = 0;
2714
2715 spin_lock(&tree->lru_lock);
2716 if (list_empty(lru))
2717 goto out;
2718
2719 do {
2720 eb = list_entry(cur, struct extent_buffer, lru);
2721 if (eb->start <= start && eb->start + eb->len > start) {
2722 eb->flags &= ~EXTENT_UPTODATE;
2723 }
2724 cur = cur->next;
2725 } while (cur != lru);
2726out:
2727 spin_unlock(&tree->lru_lock);
2728 return found;
2729} 2680}
2730 2681
2731static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, 2682static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree,
@@ -2736,15 +2687,7 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree,
2736 struct extent_buffer *eb = NULL; 2687 struct extent_buffer *eb = NULL;
2737 unsigned long flags; 2688 unsigned long flags;
2738 2689
2739 spin_lock(&tree->lru_lock);
2740 eb = find_lru(tree, start, len);
2741 spin_unlock(&tree->lru_lock);
2742 if (eb) {
2743 return eb;
2744 }
2745
2746 eb = kmem_cache_zalloc(extent_buffer_cache, mask); 2690 eb = kmem_cache_zalloc(extent_buffer_cache, mask);
2747 INIT_LIST_HEAD(&eb->lru);
2748 eb->start = start; 2691 eb->start = start;
2749 eb->len = len; 2692 eb->len = len;
2750 spin_lock_irqsave(&leak_lock, flags); 2693 spin_lock_irqsave(&leak_lock, flags);
@@ -2773,17 +2716,24 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
2773 unsigned long i; 2716 unsigned long i;
2774 unsigned long index = start >> PAGE_CACHE_SHIFT; 2717 unsigned long index = start >> PAGE_CACHE_SHIFT;
2775 struct extent_buffer *eb; 2718 struct extent_buffer *eb;
2719 struct extent_buffer *exists = NULL;
2776 struct page *p; 2720 struct page *p;
2777 struct address_space *mapping = tree->mapping; 2721 struct address_space *mapping = tree->mapping;
2778 int uptodate = 1; 2722 int uptodate = 1;
2779 2723
2724 spin_lock(&tree->buffer_lock);
2725 eb = buffer_search(tree, start);
2726 if (eb) {
2727 atomic_inc(&eb->refs);
2728 spin_unlock(&tree->buffer_lock);
2729 return eb;
2730 }
2731 spin_unlock(&tree->buffer_lock);
2732
2780 eb = __alloc_extent_buffer(tree, start, len, mask); 2733 eb = __alloc_extent_buffer(tree, start, len, mask);
2781 if (!eb) 2734 if (!eb)
2782 return NULL; 2735 return NULL;
2783 2736
2784 if (eb->flags & EXTENT_BUFFER_FILLED)
2785 goto lru_add;
2786
2787 if (page0) { 2737 if (page0) {
2788 eb->first_page = page0; 2738 eb->first_page = page0;
2789 i = 1; 2739 i = 1;
@@ -2800,7 +2750,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
2800 p = find_or_create_page(mapping, index, mask | __GFP_HIGHMEM); 2750 p = find_or_create_page(mapping, index, mask | __GFP_HIGHMEM);
2801 if (!p) { 2751 if (!p) {
2802 WARN_ON(1); 2752 WARN_ON(1);
2803 goto fail; 2753 goto free_eb;
2804 } 2754 }
2805 set_page_extent_mapped(p); 2755 set_page_extent_mapped(p);
2806 mark_page_accessed(p); 2756 mark_page_accessed(p);
@@ -2818,25 +2768,28 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
2818 eb->flags |= EXTENT_UPTODATE; 2768 eb->flags |= EXTENT_UPTODATE;
2819 eb->flags |= EXTENT_BUFFER_FILLED; 2769 eb->flags |= EXTENT_BUFFER_FILLED;
2820 2770
2821lru_add: 2771 spin_lock(&tree->buffer_lock);
2822 spin_lock(&tree->lru_lock); 2772 exists = buffer_tree_insert(tree, start, &eb->rb_node);
2823 add_lru(tree, eb); 2773 if (exists) {
2824 spin_unlock(&tree->lru_lock); 2774 /* add one reference for the caller */
2775 atomic_inc(&exists->refs);
2776 spin_unlock(&tree->buffer_lock);
2777 goto free_eb;
2778 }
2779 spin_unlock(&tree->buffer_lock);
2780
2781 /* add one reference for the tree */
2782 atomic_inc(&eb->refs);
2825 return eb; 2783 return eb;
2826 2784
2827fail: 2785free_eb:
2828 spin_lock(&tree->lru_lock);
2829 list_del_init(&eb->lru);
2830 spin_unlock(&tree->lru_lock);
2831 if (!atomic_dec_and_test(&eb->refs)) 2786 if (!atomic_dec_and_test(&eb->refs))
2832 return NULL; 2787 return exists;
2833 for (index = 1; index < i; index++) { 2788 for (index = 1; index < i; index++)
2834 page_cache_release(extent_buffer_page(eb, index)); 2789 page_cache_release(extent_buffer_page(eb, index));
2835 } 2790 page_cache_release(extent_buffer_page(eb, 0));
2836 if (i > 0)
2837 page_cache_release(extent_buffer_page(eb, 0));
2838 __free_extent_buffer(eb); 2791 __free_extent_buffer(eb);
2839 return NULL; 2792 return exists;
2840} 2793}
2841EXPORT_SYMBOL(alloc_extent_buffer); 2794EXPORT_SYMBOL(alloc_extent_buffer);
2842 2795
@@ -2844,89 +2797,27 @@ struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree,
2844 u64 start, unsigned long len, 2797 u64 start, unsigned long len,
2845 gfp_t mask) 2798 gfp_t mask)
2846{ 2799{
2847 unsigned long num_pages = num_extent_pages(start, len);
2848 unsigned long i;
2849 unsigned long index = start >> PAGE_CACHE_SHIFT;
2850 struct extent_buffer *eb; 2800 struct extent_buffer *eb;
2851 struct page *p;
2852 struct address_space *mapping = tree->mapping;
2853 int uptodate = 1;
2854 2801
2855 eb = __alloc_extent_buffer(tree, start, len, mask); 2802 spin_lock(&tree->buffer_lock);
2856 if (!eb) 2803 eb = buffer_search(tree, start);
2857 return NULL; 2804 if (eb)
2858 2805 atomic_inc(&eb->refs);
2859 if (eb->flags & EXTENT_BUFFER_FILLED) 2806 spin_unlock(&tree->buffer_lock);
2860 goto lru_add;
2861
2862 for (i = 0; i < num_pages; i++, index++) {
2863 p = find_get_page(mapping, index);
2864 if (!p) {
2865 goto fail;
2866 }
2867 if (TestSetPageLocked(p)) {
2868 page_cache_release(p);
2869 goto fail;
2870 }
2871
2872 set_page_extent_mapped(p);
2873 mark_page_accessed(p);
2874
2875 if (i == 0) {
2876 eb->first_page = p;
2877 set_page_extent_head(p, len);
2878 } else {
2879 set_page_private(p, EXTENT_PAGE_PRIVATE);
2880 }
2881
2882 if (!PageUptodate(p))
2883 uptodate = 0;
2884 unlock_page(p);
2885 }
2886 if (uptodate)
2887 eb->flags |= EXTENT_UPTODATE;
2888 eb->flags |= EXTENT_BUFFER_FILLED;
2889 2807
2890lru_add:
2891 spin_lock(&tree->lru_lock);
2892 add_lru(tree, eb);
2893 spin_unlock(&tree->lru_lock);
2894 return eb; 2808 return eb;
2895fail:
2896 spin_lock(&tree->lru_lock);
2897 list_del_init(&eb->lru);
2898 spin_unlock(&tree->lru_lock);
2899 if (!atomic_dec_and_test(&eb->refs))
2900 return NULL;
2901 for (index = 1; index < i; index++) {
2902 page_cache_release(extent_buffer_page(eb, index));
2903 }
2904 if (i > 0)
2905 page_cache_release(extent_buffer_page(eb, 0));
2906 __free_extent_buffer(eb);
2907 return NULL;
2908} 2809}
2909EXPORT_SYMBOL(find_extent_buffer); 2810EXPORT_SYMBOL(find_extent_buffer);
2910 2811
2911void free_extent_buffer(struct extent_buffer *eb) 2812void free_extent_buffer(struct extent_buffer *eb)
2912{ 2813{
2913 unsigned long i;
2914 unsigned long num_pages;
2915
2916 if (!eb) 2814 if (!eb)
2917 return; 2815 return;
2918 2816
2919 if (!atomic_dec_and_test(&eb->refs)) 2817 if (!atomic_dec_and_test(&eb->refs))
2920 return; 2818 return;
2921 2819
2922 WARN_ON(!list_empty(&eb->lru)); 2820 WARN_ON(1);
2923 num_pages = num_extent_pages(eb->start, eb->len);
2924
2925 for (i = 1; i < num_pages; i++) {
2926 page_cache_release(extent_buffer_page(eb, i));
2927 }
2928 page_cache_release(extent_buffer_page(eb, 0));
2929 __free_extent_buffer(eb);
2930} 2821}
2931EXPORT_SYMBOL(free_extent_buffer); 2822EXPORT_SYMBOL(free_extent_buffer);
2932 2823
@@ -3583,3 +3474,35 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
3583 } 3474 }
3584} 3475}
3585EXPORT_SYMBOL(memmove_extent_buffer); 3476EXPORT_SYMBOL(memmove_extent_buffer);
3477
3478int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page)
3479{
3480 u64 start = page_offset(page);
3481 struct extent_buffer *eb;
3482 int ret = 1;
3483 unsigned long i;
3484 unsigned long num_pages;
3485
3486 spin_lock(&tree->buffer_lock);
3487 eb = buffer_search(tree, start);
3488 if (!eb)
3489 goto out;
3490
3491 if (atomic_read(&eb->refs) > 1) {
3492 ret = 0;
3493 goto out;
3494 }
3495 /* at this point we can safely release the extent buffer */
3496 num_pages = num_extent_pages(eb->start, eb->len);
3497 for (i = 0; i < num_pages; i++) {
3498 struct page *page = extent_buffer_page(eb, i);
3499 page_cache_release(page);
3500 }
3501 rb_erase(&eb->rb_node, &tree->buffer);
3502 __free_extent_buffer(eb);
3503out:
3504 spin_unlock(&tree->buffer_lock);
3505 return ret;
3506}
3507EXPORT_SYMBOL(try_release_extent_buffer);
3508
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 23affd27af5e..dd367617d780 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -54,13 +54,12 @@ struct extent_io_ops {
54 54
55struct extent_io_tree { 55struct extent_io_tree {
56 struct rb_root state; 56 struct rb_root state;
57 struct rb_root buffer;
57 struct address_space *mapping; 58 struct address_space *mapping;
58 u64 dirty_bytes; 59 u64 dirty_bytes;
59 spinlock_t lock; 60 spinlock_t lock;
61 spinlock_t buffer_lock;
60 struct extent_io_ops *ops; 62 struct extent_io_ops *ops;
61 spinlock_t lru_lock;
62 struct list_head buffer_lru;
63 int lru_size;
64 struct extent_state *last; 63 struct extent_state *last;
65}; 64};
66 65
@@ -87,10 +86,10 @@ struct extent_buffer {
87 unsigned long map_start; 86 unsigned long map_start;
88 unsigned long map_len; 87 unsigned long map_len;
89 struct page *first_page; 88 struct page *first_page;
90 struct list_head lru;
91 atomic_t refs; 89 atomic_t refs;
92 int flags; 90 int flags;
93 struct list_head leak_list; 91 struct list_head leak_list;
92 struct rb_node rb_node;
94}; 93};
95 94
96struct extent_map_tree; 95struct extent_map_tree;
@@ -112,10 +111,10 @@ typedef struct extent_map *(get_extent_t)(struct inode *inode,
112 111
113void extent_io_tree_init(struct extent_io_tree *tree, 112void extent_io_tree_init(struct extent_io_tree *tree,
114 struct address_space *mapping, gfp_t mask); 113 struct address_space *mapping, gfp_t mask);
115void extent_io_tree_empty_lru(struct extent_io_tree *tree);
116int try_release_extent_mapping(struct extent_map_tree *map, 114int try_release_extent_mapping(struct extent_map_tree *map,
117 struct extent_io_tree *tree, struct page *page, 115 struct extent_io_tree *tree, struct page *page,
118 gfp_t mask); 116 gfp_t mask);
117int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page);
119int try_release_extent_state(struct extent_map_tree *map, 118int try_release_extent_state(struct extent_map_tree *map,
120 struct extent_io_tree *tree, struct page *page, 119 struct extent_io_tree *tree, struct page *page,
121 gfp_t mask); 120 gfp_t mask);
@@ -241,8 +240,6 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long offset,
241 unsigned long *map_start, 240 unsigned long *map_start,
242 unsigned long *map_len, int km); 241 unsigned long *map_len, int km);
243void unmap_extent_buffer(struct extent_buffer *eb, char *token, int km); 242void unmap_extent_buffer(struct extent_buffer *eb, char *token, int km);
244int invalidate_extent_lru(struct extent_io_tree *tree, u64 start,
245 unsigned long len);
246int release_extent_buffer_tail_pages(struct extent_buffer *eb); 243int release_extent_buffer_tail_pages(struct extent_buffer *eb);
247int extent_range_uptodate(struct extent_io_tree *tree, 244int extent_range_uptodate(struct extent_io_tree *tree,
248 u64 start, u64 end); 245 u64 start, u64 end);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 8fb6dc25e7a5..60852ada658e 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2670,7 +2670,6 @@ static int __btrfs_releasepage(struct page *page, gfp_t gfp_flags)
2670 map = &BTRFS_I(page->mapping->host)->extent_tree; 2670 map = &BTRFS_I(page->mapping->host)->extent_tree;
2671 ret = try_release_extent_mapping(map, tree, page, gfp_flags); 2671 ret = try_release_extent_mapping(map, tree, page, gfp_flags);
2672 if (ret == 1) { 2672 if (ret == 1) {
2673 invalidate_extent_lru(tree, page_offset(page), PAGE_CACHE_SIZE);
2674 ClearPagePrivate(page); 2673 ClearPagePrivate(page);
2675 set_page_private(page, 0); 2674 set_page_private(page, 0);
2676 page_cache_release(page); 2675 page_cache_release(page);
@@ -2721,8 +2720,6 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
2721 2720
2722 ClearPageChecked(page); 2721 ClearPageChecked(page);
2723 if (PagePrivate(page)) { 2722 if (PagePrivate(page)) {
2724 invalidate_extent_lru(tree, page_offset(page),
2725 PAGE_CACHE_SIZE);
2726 ClearPagePrivate(page); 2723 ClearPagePrivate(page);
2727 set_page_private(page, 0); 2724 set_page_private(page, 0);
2728 page_cache_release(page); 2725 page_cache_release(page);