aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-02-15 02:12:00 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-15 02:12:00 -0500
commit5e30589521518bff36fd2638b3c3d69679c50436 (patch)
tree6ac985658a06b0787e4354d0d16d380ea9b16a5a /fs/btrfs/extent_io.c
parentac178ef0ae9eb44fd527d87aa9b6394e05f56e1f (diff)
parentd2f8d7ee1a9b4650b4e43325b321801264f7c37a (diff)
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Conflicts: drivers/net/wireless/iwlwifi/iwl-agn.c drivers/net/wireless/iwlwifi/iwl3945-base.c
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c132
1 files changed, 109 insertions, 23 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index e086d407f1fa..37d43b516b79 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -9,7 +9,6 @@
9#include <linux/spinlock.h> 9#include <linux/spinlock.h>
10#include <linux/blkdev.h> 10#include <linux/blkdev.h>
11#include <linux/swap.h> 11#include <linux/swap.h>
12#include <linux/version.h>
13#include <linux/writeback.h> 12#include <linux/writeback.h>
14#include <linux/pagevec.h> 13#include <linux/pagevec.h>
15#include "extent_io.h" 14#include "extent_io.h"
@@ -31,7 +30,7 @@ static LIST_HEAD(buffers);
31static LIST_HEAD(states); 30static LIST_HEAD(states);
32 31
33#define LEAK_DEBUG 0 32#define LEAK_DEBUG 0
34#ifdef LEAK_DEBUG 33#if LEAK_DEBUG
35static DEFINE_SPINLOCK(leak_lock); 34static DEFINE_SPINLOCK(leak_lock);
36#endif 35#endif
37 36
@@ -120,7 +119,7 @@ void extent_io_tree_init(struct extent_io_tree *tree,
120static struct extent_state *alloc_extent_state(gfp_t mask) 119static struct extent_state *alloc_extent_state(gfp_t mask)
121{ 120{
122 struct extent_state *state; 121 struct extent_state *state;
123#ifdef LEAK_DEBUG 122#if LEAK_DEBUG
124 unsigned long flags; 123 unsigned long flags;
125#endif 124#endif
126 125
@@ -130,7 +129,7 @@ static struct extent_state *alloc_extent_state(gfp_t mask)
130 state->state = 0; 129 state->state = 0;
131 state->private = 0; 130 state->private = 0;
132 state->tree = NULL; 131 state->tree = NULL;
133#ifdef LEAK_DEBUG 132#if LEAK_DEBUG
134 spin_lock_irqsave(&leak_lock, flags); 133 spin_lock_irqsave(&leak_lock, flags);
135 list_add(&state->leak_list, &states); 134 list_add(&state->leak_list, &states);
136 spin_unlock_irqrestore(&leak_lock, flags); 135 spin_unlock_irqrestore(&leak_lock, flags);
@@ -145,11 +144,11 @@ static void free_extent_state(struct extent_state *state)
145 if (!state) 144 if (!state)
146 return; 145 return;
147 if (atomic_dec_and_test(&state->refs)) { 146 if (atomic_dec_and_test(&state->refs)) {
148#ifdef LEAK_DEBUG 147#if LEAK_DEBUG
149 unsigned long flags; 148 unsigned long flags;
150#endif 149#endif
151 WARN_ON(state->tree); 150 WARN_ON(state->tree);
152#ifdef LEAK_DEBUG 151#if LEAK_DEBUG
153 spin_lock_irqsave(&leak_lock, flags); 152 spin_lock_irqsave(&leak_lock, flags);
154 list_del(&state->leak_list); 153 list_del(&state->leak_list);
155 spin_unlock_irqrestore(&leak_lock, flags); 154 spin_unlock_irqrestore(&leak_lock, flags);
@@ -2378,11 +2377,6 @@ static int extent_write_cache_pages(struct extent_io_tree *tree,
2378 int scanned = 0; 2377 int scanned = 0;
2379 int range_whole = 0; 2378 int range_whole = 0;
2380 2379
2381 if (wbc->nonblocking && bdi_write_congested(bdi)) {
2382 wbc->encountered_congestion = 1;
2383 return 0;
2384 }
2385
2386 pagevec_init(&pvec, 0); 2380 pagevec_init(&pvec, 0);
2387 if (wbc->range_cyclic) { 2381 if (wbc->range_cyclic) {
2388 index = mapping->writeback_index; /* Start from prev offset */ 2382 index = mapping->writeback_index; /* Start from prev offset */
@@ -2855,6 +2849,98 @@ out:
2855 return sector; 2849 return sector;
2856} 2850}
2857 2851
2852int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
2853 __u64 start, __u64 len, get_extent_t *get_extent)
2854{
2855 int ret;
2856 u64 off = start;
2857 u64 max = start + len;
2858 u32 flags = 0;
2859 u64 disko = 0;
2860 struct extent_map *em = NULL;
2861 int end = 0;
2862 u64 em_start = 0, em_len = 0;
2863 unsigned long emflags;
2864 ret = 0;
2865
2866 if (len == 0)
2867 return -EINVAL;
2868
2869 lock_extent(&BTRFS_I(inode)->io_tree, start, start + len,
2870 GFP_NOFS);
2871 em = get_extent(inode, NULL, 0, off, max - off, 0);
2872 if (!em)
2873 goto out;
2874 if (IS_ERR(em)) {
2875 ret = PTR_ERR(em);
2876 goto out;
2877 }
2878 while (!end) {
2879 off = em->start + em->len;
2880 if (off >= max)
2881 end = 1;
2882
2883 em_start = em->start;
2884 em_len = em->len;
2885
2886 disko = 0;
2887 flags = 0;
2888
2889 switch (em->block_start) {
2890 case EXTENT_MAP_LAST_BYTE:
2891 end = 1;
2892 flags |= FIEMAP_EXTENT_LAST;
2893 break;
2894 case EXTENT_MAP_HOLE:
2895 flags |= FIEMAP_EXTENT_UNWRITTEN;
2896 break;
2897 case EXTENT_MAP_INLINE:
2898 flags |= (FIEMAP_EXTENT_DATA_INLINE |
2899 FIEMAP_EXTENT_NOT_ALIGNED);
2900 break;
2901 case EXTENT_MAP_DELALLOC:
2902 flags |= (FIEMAP_EXTENT_DELALLOC |
2903 FIEMAP_EXTENT_UNKNOWN);
2904 break;
2905 default:
2906 disko = em->block_start;
2907 break;
2908 }
2909 if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags))
2910 flags |= FIEMAP_EXTENT_ENCODED;
2911
2912 emflags = em->flags;
2913 free_extent_map(em);
2914 em = NULL;
2915
2916 if (!end) {
2917 em = get_extent(inode, NULL, 0, off, max - off, 0);
2918 if (!em)
2919 goto out;
2920 if (IS_ERR(em)) {
2921 ret = PTR_ERR(em);
2922 goto out;
2923 }
2924 emflags = em->flags;
2925 }
2926 if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) {
2927 flags |= FIEMAP_EXTENT_LAST;
2928 end = 1;
2929 }
2930
2931 ret = fiemap_fill_next_extent(fieinfo, em_start, disko,
2932 em_len, flags);
2933 if (ret)
2934 goto out_free;
2935 }
2936out_free:
2937 free_extent_map(em);
2938out:
2939 unlock_extent(&BTRFS_I(inode)->io_tree, start, start + len,
2940 GFP_NOFS);
2941 return ret;
2942}
2943
2858static inline struct page *extent_buffer_page(struct extent_buffer *eb, 2944static inline struct page *extent_buffer_page(struct extent_buffer *eb,
2859 unsigned long i) 2945 unsigned long i)
2860{ 2946{
@@ -2892,15 +2978,17 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree,
2892 gfp_t mask) 2978 gfp_t mask)
2893{ 2979{
2894 struct extent_buffer *eb = NULL; 2980 struct extent_buffer *eb = NULL;
2895#ifdef LEAK_DEBUG 2981#if LEAK_DEBUG
2896 unsigned long flags; 2982 unsigned long flags;
2897#endif 2983#endif
2898 2984
2899 eb = kmem_cache_zalloc(extent_buffer_cache, mask); 2985 eb = kmem_cache_zalloc(extent_buffer_cache, mask);
2900 eb->start = start; 2986 eb->start = start;
2901 eb->len = len; 2987 eb->len = len;
2902 mutex_init(&eb->mutex); 2988 spin_lock_init(&eb->lock);
2903#ifdef LEAK_DEBUG 2989 init_waitqueue_head(&eb->lock_wq);
2990
2991#if LEAK_DEBUG
2904 spin_lock_irqsave(&leak_lock, flags); 2992 spin_lock_irqsave(&leak_lock, flags);
2905 list_add(&eb->leak_list, &buffers); 2993 list_add(&eb->leak_list, &buffers);
2906 spin_unlock_irqrestore(&leak_lock, flags); 2994 spin_unlock_irqrestore(&leak_lock, flags);
@@ -2912,7 +3000,7 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree,
2912 3000
2913static void __free_extent_buffer(struct extent_buffer *eb) 3001static void __free_extent_buffer(struct extent_buffer *eb)
2914{ 3002{
2915#ifdef LEAK_DEBUG 3003#if LEAK_DEBUG
2916 unsigned long flags; 3004 unsigned long flags;
2917 spin_lock_irqsave(&leak_lock, flags); 3005 spin_lock_irqsave(&leak_lock, flags);
2918 list_del(&eb->leak_list); 3006 list_del(&eb->leak_list);
@@ -2980,8 +3068,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
2980 unlock_page(p); 3068 unlock_page(p);
2981 } 3069 }
2982 if (uptodate) 3070 if (uptodate)
2983 eb->flags |= EXTENT_UPTODATE; 3071 set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
2984 eb->flags |= EXTENT_BUFFER_FILLED;
2985 3072
2986 spin_lock(&tree->buffer_lock); 3073 spin_lock(&tree->buffer_lock);
2987 exists = buffer_tree_insert(tree, start, &eb->rb_node); 3074 exists = buffer_tree_insert(tree, start, &eb->rb_node);
@@ -3135,7 +3222,7 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
3135 unsigned long num_pages; 3222 unsigned long num_pages;
3136 3223
3137 num_pages = num_extent_pages(eb->start, eb->len); 3224 num_pages = num_extent_pages(eb->start, eb->len);
3138 eb->flags &= ~EXTENT_UPTODATE; 3225 clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
3139 3226
3140 clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, 3227 clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
3141 GFP_NOFS); 3228 GFP_NOFS);
@@ -3206,7 +3293,7 @@ int extent_buffer_uptodate(struct extent_io_tree *tree,
3206 struct page *page; 3293 struct page *page;
3207 int pg_uptodate = 1; 3294 int pg_uptodate = 1;
3208 3295
3209 if (eb->flags & EXTENT_UPTODATE) 3296 if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
3210 return 1; 3297 return 1;
3211 3298
3212 ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1, 3299 ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1,
@@ -3242,7 +3329,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
3242 struct bio *bio = NULL; 3329 struct bio *bio = NULL;
3243 unsigned long bio_flags = 0; 3330 unsigned long bio_flags = 0;
3244 3331
3245 if (eb->flags & EXTENT_UPTODATE) 3332 if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
3246 return 0; 3333 return 0;
3247 3334
3248 if (test_range_bit(tree, eb->start, eb->start + eb->len - 1, 3335 if (test_range_bit(tree, eb->start, eb->start + eb->len - 1,
@@ -3273,7 +3360,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
3273 } 3360 }
3274 if (all_uptodate) { 3361 if (all_uptodate) {
3275 if (start_i == 0) 3362 if (start_i == 0)
3276 eb->flags |= EXTENT_UPTODATE; 3363 set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
3277 goto unlock_exit; 3364 goto unlock_exit;
3278 } 3365 }
3279 3366
@@ -3309,7 +3396,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
3309 } 3396 }
3310 3397
3311 if (!ret) 3398 if (!ret)
3312 eb->flags |= EXTENT_UPTODATE; 3399 set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
3313 return ret; 3400 return ret;
3314 3401
3315unlock_exit: 3402unlock_exit:
@@ -3406,7 +3493,6 @@ int map_extent_buffer(struct extent_buffer *eb, unsigned long start,
3406 unmap_extent_buffer(eb, eb->map_token, km); 3493 unmap_extent_buffer(eb, eb->map_token, km);
3407 eb->map_token = NULL; 3494 eb->map_token = NULL;
3408 save = 1; 3495 save = 1;
3409 WARN_ON(!mutex_is_locked(&eb->mutex));
3410 } 3496 }
3411 err = map_private_extent_buffer(eb, start, min_len, token, map, 3497 err = map_private_extent_buffer(eb, start, min_len, token, map,
3412 map_start, map_len, km); 3498 map_start, map_len, km);