diff options
author | David S. Miller <davem@davemloft.net> | 2009-02-15 02:12:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-15 02:12:00 -0500 |
commit | 5e30589521518bff36fd2638b3c3d69679c50436 (patch) | |
tree | 6ac985658a06b0787e4354d0d16d380ea9b16a5a /fs/btrfs/extent_io.c | |
parent | ac178ef0ae9eb44fd527d87aa9b6394e05f56e1f (diff) | |
parent | d2f8d7ee1a9b4650b4e43325b321801264f7c37a (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.c | 132 |
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); | |||
31 | static LIST_HEAD(states); | 30 | static LIST_HEAD(states); |
32 | 31 | ||
33 | #define LEAK_DEBUG 0 | 32 | #define LEAK_DEBUG 0 |
34 | #ifdef LEAK_DEBUG | 33 | #if LEAK_DEBUG |
35 | static DEFINE_SPINLOCK(leak_lock); | 34 | static DEFINE_SPINLOCK(leak_lock); |
36 | #endif | 35 | #endif |
37 | 36 | ||
@@ -120,7 +119,7 @@ void extent_io_tree_init(struct extent_io_tree *tree, | |||
120 | static struct extent_state *alloc_extent_state(gfp_t mask) | 119 | static 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 | ||
2852 | int 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 | } | ||
2936 | out_free: | ||
2937 | free_extent_map(em); | ||
2938 | out: | ||
2939 | unlock_extent(&BTRFS_I(inode)->io_tree, start, start + len, | ||
2940 | GFP_NOFS); | ||
2941 | return ret; | ||
2942 | } | ||
2943 | |||
2858 | static inline struct page *extent_buffer_page(struct extent_buffer *eb, | 2944 | static 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 | ||
2913 | static void __free_extent_buffer(struct extent_buffer *eb) | 3001 | static 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 | ||
3315 | unlock_exit: | 3402 | unlock_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); |