aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/extent_io.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index d74e6af9b53a..6e3b326346a7 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3104,6 +3104,39 @@ static void __free_extent_buffer(struct extent_buffer *eb)
3104 kmem_cache_free(extent_buffer_cache, eb); 3104 kmem_cache_free(extent_buffer_cache, eb);
3105} 3105}
3106 3106
3107/*
3108 * Helper for releasing extent buffer page.
3109 */
3110static void btrfs_release_extent_buffer_page(struct extent_buffer *eb,
3111 unsigned long start_idx)
3112{
3113 unsigned long index;
3114 struct page *page;
3115
3116 if (!eb->first_page)
3117 return;
3118
3119 index = num_extent_pages(eb->start, eb->len);
3120 if (start_idx >= index)
3121 return;
3122
3123 do {
3124 index--;
3125 page = extent_buffer_page(eb, index);
3126 if (page)
3127 page_cache_release(page);
3128 } while (index != start_idx);
3129}
3130
3131/*
3132 * Helper for releasing the extent buffer.
3133 */
3134static inline void btrfs_release_extent_buffer(struct extent_buffer *eb)
3135{
3136 btrfs_release_extent_buffer_page(eb, 0);
3137 __free_extent_buffer(eb);
3138}
3139
3107struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, 3140struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
3108 u64 start, unsigned long len, 3141 u64 start, unsigned long len,
3109 struct page *page0, 3142 struct page *page0,
@@ -3181,10 +3214,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
3181free_eb: 3214free_eb:
3182 if (!atomic_dec_and_test(&eb->refs)) 3215 if (!atomic_dec_and_test(&eb->refs))
3183 return exists; 3216 return exists;
3184 for (index = 1; index < i; index++) 3217 btrfs_release_extent_buffer(eb);
3185 page_cache_release(extent_buffer_page(eb, index));
3186 page_cache_release(extent_buffer_page(eb, 0));
3187 __free_extent_buffer(eb);
3188 return exists; 3218 return exists;
3189} 3219}
3190 3220
@@ -3838,8 +3868,6 @@ int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page)
3838 u64 start = page_offset(page); 3868 u64 start = page_offset(page);
3839 struct extent_buffer *eb; 3869 struct extent_buffer *eb;
3840 int ret = 1; 3870 int ret = 1;
3841 unsigned long i;
3842 unsigned long num_pages;
3843 3871
3844 spin_lock(&tree->buffer_lock); 3872 spin_lock(&tree->buffer_lock);
3845 eb = buffer_search(tree, start); 3873 eb = buffer_search(tree, start);
@@ -3854,12 +3882,10 @@ int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page)
3854 ret = 0; 3882 ret = 0;
3855 goto out; 3883 goto out;
3856 } 3884 }
3857 /* at this point we can safely release the extent buffer */ 3885
3858 num_pages = num_extent_pages(eb->start, eb->len);
3859 for (i = 0; i < num_pages; i++)
3860 page_cache_release(extent_buffer_page(eb, i));
3861 rb_erase(&eb->rb_node, &tree->buffer); 3886 rb_erase(&eb->rb_node, &tree->buffer);
3862 __free_extent_buffer(eb); 3887 /* at this point we can safely release the extent buffer */
3888 btrfs_release_extent_buffer(eb);
3863out: 3889out:
3864 spin_unlock(&tree->buffer_lock); 3890 spin_unlock(&tree->buffer_lock);
3865 return ret; 3891 return ret;