diff options
author | Josef Bacik <josef@redhat.com> | 2010-02-03 14:33:23 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2010-03-15 11:00:13 -0400 |
commit | 2ac55d41b5d6bf49e76bc85db5431240617e2f8f (patch) | |
tree | ee8e2a716ef0b50388ef5e4a86387ec0499bca89 /fs | |
parent | 5a1a3df1f6c86926cfe8657e6f9b4b4c2f467d60 (diff) |
Btrfs: cache the extent state everywhere we possibly can V2
This patch just goes through and fixes everybody that does
lock_extent()
blah
unlock_extent()
to use
lock_extent_bits()
blah
unlock_extent_cached()
and pass around a extent_state so we only have to do the searches once per
function. This gives me about a 3 mb/s boots on my random write test. I have
not converted some things, like the relocation and ioctl's, since they aren't
heavily used and the relocation stuff is in the middle of being re-written. I
also changed the clear_extent_bit() to only unset the cached state if we are
clearing EXTENT_LOCKED and related stuff, so we can do things like this
lock_extent_bits()
clear delalloc bits
unlock_extent_cached()
without losing our cached state. I tested this thoroughly and turned on
LEAK_DEBUG to make sure we weren't leaking extent states, everything worked out
fine.
Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 15 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 11 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 61 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 10 | ||||
-rw-r--r-- | fs/btrfs/file.c | 23 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 111 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 2 |
9 files changed, 148 insertions, 90 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3a36b1fb553a..3f704a816137 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2311,7 +2311,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, | |||
2311 | u32 min_type); | 2311 | u32 min_type); |
2312 | 2312 | ||
2313 | int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); | 2313 | int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); |
2314 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); | 2314 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, |
2315 | struct extent_state **cached_state); | ||
2315 | int btrfs_writepages(struct address_space *mapping, | 2316 | int btrfs_writepages(struct address_space *mapping, |
2316 | struct writeback_control *wbc); | 2317 | struct writeback_control *wbc); |
2317 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | 2318 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 0427183e3e05..11d0ad30e203 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -263,13 +263,15 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, | |||
263 | static int verify_parent_transid(struct extent_io_tree *io_tree, | 263 | static int verify_parent_transid(struct extent_io_tree *io_tree, |
264 | struct extent_buffer *eb, u64 parent_transid) | 264 | struct extent_buffer *eb, u64 parent_transid) |
265 | { | 265 | { |
266 | struct extent_state *cached_state = NULL; | ||
266 | int ret; | 267 | int ret; |
267 | 268 | ||
268 | if (!parent_transid || btrfs_header_generation(eb) == parent_transid) | 269 | if (!parent_transid || btrfs_header_generation(eb) == parent_transid) |
269 | return 0; | 270 | return 0; |
270 | 271 | ||
271 | lock_extent(io_tree, eb->start, eb->start + eb->len - 1, GFP_NOFS); | 272 | lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1, |
272 | if (extent_buffer_uptodate(io_tree, eb) && | 273 | 0, &cached_state, GFP_NOFS); |
274 | if (extent_buffer_uptodate(io_tree, eb, cached_state) && | ||
273 | btrfs_header_generation(eb) == parent_transid) { | 275 | btrfs_header_generation(eb) == parent_transid) { |
274 | ret = 0; | 276 | ret = 0; |
275 | goto out; | 277 | goto out; |
@@ -282,10 +284,10 @@ static int verify_parent_transid(struct extent_io_tree *io_tree, | |||
282 | (unsigned long long)btrfs_header_generation(eb)); | 284 | (unsigned long long)btrfs_header_generation(eb)); |
283 | } | 285 | } |
284 | ret = 1; | 286 | ret = 1; |
285 | clear_extent_buffer_uptodate(io_tree, eb); | 287 | clear_extent_buffer_uptodate(io_tree, eb, &cached_state); |
286 | out: | 288 | out: |
287 | unlock_extent(io_tree, eb->start, eb->start + eb->len - 1, | 289 | unlock_extent_cached(io_tree, eb->start, eb->start + eb->len - 1, |
288 | GFP_NOFS); | 290 | &cached_state, GFP_NOFS); |
289 | return ret; | 291 | return ret; |
290 | } | 292 | } |
291 | 293 | ||
@@ -2497,7 +2499,8 @@ int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid) | |||
2497 | int ret; | 2499 | int ret; |
2498 | struct inode *btree_inode = buf->first_page->mapping->host; | 2500 | struct inode *btree_inode = buf->first_page->mapping->host; |
2499 | 2501 | ||
2500 | ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf); | 2502 | ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf, |
2503 | NULL); | ||
2501 | if (!ret) | 2504 | if (!ret) |
2502 | return ret; | 2505 | return ret; |
2503 | 2506 | ||
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 559f72489b3b..1727b26fb194 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -6561,6 +6561,7 @@ static noinline int invalidate_extent_cache(struct btrfs_root *root, | |||
6561 | struct btrfs_key key; | 6561 | struct btrfs_key key; |
6562 | struct inode *inode = NULL; | 6562 | struct inode *inode = NULL; |
6563 | struct btrfs_file_extent_item *fi; | 6563 | struct btrfs_file_extent_item *fi; |
6564 | struct extent_state *cached_state = NULL; | ||
6564 | u64 num_bytes; | 6565 | u64 num_bytes; |
6565 | u64 skip_objectid = 0; | 6566 | u64 skip_objectid = 0; |
6566 | u32 nritems; | 6567 | u32 nritems; |
@@ -6589,12 +6590,14 @@ static noinline int invalidate_extent_cache(struct btrfs_root *root, | |||
6589 | } | 6590 | } |
6590 | num_bytes = btrfs_file_extent_num_bytes(leaf, fi); | 6591 | num_bytes = btrfs_file_extent_num_bytes(leaf, fi); |
6591 | 6592 | ||
6592 | lock_extent(&BTRFS_I(inode)->io_tree, key.offset, | 6593 | lock_extent_bits(&BTRFS_I(inode)->io_tree, key.offset, |
6593 | key.offset + num_bytes - 1, GFP_NOFS); | 6594 | key.offset + num_bytes - 1, 0, &cached_state, |
6595 | GFP_NOFS); | ||
6594 | btrfs_drop_extent_cache(inode, key.offset, | 6596 | btrfs_drop_extent_cache(inode, key.offset, |
6595 | key.offset + num_bytes - 1, 1); | 6597 | key.offset + num_bytes - 1, 1); |
6596 | unlock_extent(&BTRFS_I(inode)->io_tree, key.offset, | 6598 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, key.offset, |
6597 | key.offset + num_bytes - 1, GFP_NOFS); | 6599 | key.offset + num_bytes - 1, &cached_state, |
6600 | GFP_NOFS); | ||
6598 | cond_resched(); | 6601 | cond_resched(); |
6599 | } | 6602 | } |
6600 | iput(inode); | 6603 | iput(inode); |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 3c17c9eb0d98..c99121ac5d6b 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -513,7 +513,10 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, | |||
513 | u64 last_end; | 513 | u64 last_end; |
514 | int err; | 514 | int err; |
515 | int set = 0; | 515 | int set = 0; |
516 | int clear = 0; | ||
516 | 517 | ||
518 | if (bits & (EXTENT_IOBITS | EXTENT_BOUNDARY)) | ||
519 | clear = 1; | ||
517 | again: | 520 | again: |
518 | if (!prealloc && (mask & __GFP_WAIT)) { | 521 | if (!prealloc && (mask & __GFP_WAIT)) { |
519 | prealloc = alloc_extent_state(mask); | 522 | prealloc = alloc_extent_state(mask); |
@@ -524,14 +527,20 @@ again: | |||
524 | spin_lock(&tree->lock); | 527 | spin_lock(&tree->lock); |
525 | if (cached_state) { | 528 | if (cached_state) { |
526 | cached = *cached_state; | 529 | cached = *cached_state; |
527 | *cached_state = NULL; | 530 | |
528 | cached_state = NULL; | 531 | if (clear) { |
532 | *cached_state = NULL; | ||
533 | cached_state = NULL; | ||
534 | } | ||
535 | |||
529 | if (cached && cached->tree && cached->start == start) { | 536 | if (cached && cached->tree && cached->start == start) { |
530 | atomic_dec(&cached->refs); | 537 | if (clear) |
538 | atomic_dec(&cached->refs); | ||
531 | state = cached; | 539 | state = cached; |
532 | goto hit_next; | 540 | goto hit_next; |
533 | } | 541 | } |
534 | free_extent_state(cached); | 542 | if (clear) |
543 | free_extent_state(cached); | ||
535 | } | 544 | } |
536 | /* | 545 | /* |
537 | * this search will find the extents that end after | 546 | * this search will find the extents that end after |
@@ -946,11 +955,11 @@ int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, | |||
946 | } | 955 | } |
947 | 956 | ||
948 | int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, | 957 | int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, |
949 | gfp_t mask) | 958 | struct extent_state **cached_state, gfp_t mask) |
950 | { | 959 | { |
951 | return set_extent_bit(tree, start, end, | 960 | return set_extent_bit(tree, start, end, |
952 | EXTENT_DELALLOC | EXTENT_DIRTY | EXTENT_UPTODATE, | 961 | EXTENT_DELALLOC | EXTENT_DIRTY | EXTENT_UPTODATE, |
953 | 0, NULL, NULL, mask); | 962 | 0, NULL, cached_state, mask); |
954 | } | 963 | } |
955 | 964 | ||
956 | int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, | 965 | int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, |
@@ -984,10 +993,11 @@ int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, | |||
984 | } | 993 | } |
985 | 994 | ||
986 | static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, | 995 | static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, |
987 | u64 end, gfp_t mask) | 996 | u64 end, struct extent_state **cached_state, |
997 | gfp_t mask) | ||
988 | { | 998 | { |
989 | return clear_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, 0, | 999 | return clear_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, 0, |
990 | NULL, mask); | 1000 | cached_state, mask); |
991 | } | 1001 | } |
992 | 1002 | ||
993 | int wait_on_extent_writeback(struct extent_io_tree *tree, u64 start, u64 end) | 1003 | int wait_on_extent_writeback(struct extent_io_tree *tree, u64 start, u64 end) |
@@ -1727,7 +1737,7 @@ static void end_bio_extent_writepage(struct bio *bio, int err) | |||
1727 | } | 1737 | } |
1728 | 1738 | ||
1729 | if (!uptodate) { | 1739 | if (!uptodate) { |
1730 | clear_extent_uptodate(tree, start, end, GFP_NOFS); | 1740 | clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS); |
1731 | ClearPageUptodate(page); | 1741 | ClearPageUptodate(page); |
1732 | SetPageError(page); | 1742 | SetPageError(page); |
1733 | } | 1743 | } |
@@ -2710,6 +2720,7 @@ int extent_readpages(struct extent_io_tree *tree, | |||
2710 | int extent_invalidatepage(struct extent_io_tree *tree, | 2720 | int extent_invalidatepage(struct extent_io_tree *tree, |
2711 | struct page *page, unsigned long offset) | 2721 | struct page *page, unsigned long offset) |
2712 | { | 2722 | { |
2723 | struct extent_state *cached_state = NULL; | ||
2713 | u64 start = ((u64)page->index << PAGE_CACHE_SHIFT); | 2724 | u64 start = ((u64)page->index << PAGE_CACHE_SHIFT); |
2714 | u64 end = start + PAGE_CACHE_SIZE - 1; | 2725 | u64 end = start + PAGE_CACHE_SIZE - 1; |
2715 | size_t blocksize = page->mapping->host->i_sb->s_blocksize; | 2726 | size_t blocksize = page->mapping->host->i_sb->s_blocksize; |
@@ -2718,12 +2729,12 @@ int extent_invalidatepage(struct extent_io_tree *tree, | |||
2718 | if (start > end) | 2729 | if (start > end) |
2719 | return 0; | 2730 | return 0; |
2720 | 2731 | ||
2721 | lock_extent(tree, start, end, GFP_NOFS); | 2732 | lock_extent_bits(tree, start, end, 0, &cached_state, GFP_NOFS); |
2722 | wait_on_page_writeback(page); | 2733 | wait_on_page_writeback(page); |
2723 | clear_extent_bit(tree, start, end, | 2734 | clear_extent_bit(tree, start, end, |
2724 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | | 2735 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | |
2725 | EXTENT_DO_ACCOUNTING, | 2736 | EXTENT_DO_ACCOUNTING, |
2726 | 1, 1, NULL, GFP_NOFS); | 2737 | 1, 1, &cached_state, GFP_NOFS); |
2727 | return 0; | 2738 | return 0; |
2728 | } | 2739 | } |
2729 | 2740 | ||
@@ -2926,16 +2937,17 @@ sector_t extent_bmap(struct address_space *mapping, sector_t iblock, | |||
2926 | get_extent_t *get_extent) | 2937 | get_extent_t *get_extent) |
2927 | { | 2938 | { |
2928 | struct inode *inode = mapping->host; | 2939 | struct inode *inode = mapping->host; |
2940 | struct extent_state *cached_state = NULL; | ||
2929 | u64 start = iblock << inode->i_blkbits; | 2941 | u64 start = iblock << inode->i_blkbits; |
2930 | sector_t sector = 0; | 2942 | sector_t sector = 0; |
2931 | size_t blksize = (1 << inode->i_blkbits); | 2943 | size_t blksize = (1 << inode->i_blkbits); |
2932 | struct extent_map *em; | 2944 | struct extent_map *em; |
2933 | 2945 | ||
2934 | lock_extent(&BTRFS_I(inode)->io_tree, start, start + blksize - 1, | 2946 | lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + blksize - 1, |
2935 | GFP_NOFS); | 2947 | 0, &cached_state, GFP_NOFS); |
2936 | em = get_extent(inode, NULL, 0, start, blksize, 0); | 2948 | em = get_extent(inode, NULL, 0, start, blksize, 0); |
2937 | unlock_extent(&BTRFS_I(inode)->io_tree, start, start + blksize - 1, | 2949 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, |
2938 | GFP_NOFS); | 2950 | start + blksize - 1, &cached_state, GFP_NOFS); |
2939 | if (!em || IS_ERR(em)) | 2951 | if (!em || IS_ERR(em)) |
2940 | return 0; | 2952 | return 0; |
2941 | 2953 | ||
@@ -2957,6 +2969,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
2957 | u32 flags = 0; | 2969 | u32 flags = 0; |
2958 | u64 disko = 0; | 2970 | u64 disko = 0; |
2959 | struct extent_map *em = NULL; | 2971 | struct extent_map *em = NULL; |
2972 | struct extent_state *cached_state = NULL; | ||
2960 | int end = 0; | 2973 | int end = 0; |
2961 | u64 em_start = 0, em_len = 0; | 2974 | u64 em_start = 0, em_len = 0; |
2962 | unsigned long emflags; | 2975 | unsigned long emflags; |
@@ -2965,8 +2978,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
2965 | if (len == 0) | 2978 | if (len == 0) |
2966 | return -EINVAL; | 2979 | return -EINVAL; |
2967 | 2980 | ||
2968 | lock_extent(&BTRFS_I(inode)->io_tree, start, start + len, | 2981 | lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0, |
2969 | GFP_NOFS); | 2982 | &cached_state, GFP_NOFS); |
2970 | em = get_extent(inode, NULL, 0, off, max - off, 0); | 2983 | em = get_extent(inode, NULL, 0, off, max - off, 0); |
2971 | if (!em) | 2984 | if (!em) |
2972 | goto out; | 2985 | goto out; |
@@ -3029,8 +3042,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
3029 | out_free: | 3042 | out_free: |
3030 | free_extent_map(em); | 3043 | free_extent_map(em); |
3031 | out: | 3044 | out: |
3032 | unlock_extent(&BTRFS_I(inode)->io_tree, start, start + len, | 3045 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len, |
3033 | GFP_NOFS); | 3046 | &cached_state, GFP_NOFS); |
3034 | return ret; | 3047 | return ret; |
3035 | } | 3048 | } |
3036 | 3049 | ||
@@ -3270,7 +3283,8 @@ int set_extent_buffer_dirty(struct extent_io_tree *tree, | |||
3270 | } | 3283 | } |
3271 | 3284 | ||
3272 | int clear_extent_buffer_uptodate(struct extent_io_tree *tree, | 3285 | int clear_extent_buffer_uptodate(struct extent_io_tree *tree, |
3273 | struct extent_buffer *eb) | 3286 | struct extent_buffer *eb, |
3287 | struct extent_state **cached_state) | ||
3274 | { | 3288 | { |
3275 | unsigned long i; | 3289 | unsigned long i; |
3276 | struct page *page; | 3290 | struct page *page; |
@@ -3280,7 +3294,7 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree, | |||
3280 | clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); | 3294 | clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); |
3281 | 3295 | ||
3282 | clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, | 3296 | clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, |
3283 | GFP_NOFS); | 3297 | cached_state, GFP_NOFS); |
3284 | for (i = 0; i < num_pages; i++) { | 3298 | for (i = 0; i < num_pages; i++) { |
3285 | page = extent_buffer_page(eb, i); | 3299 | page = extent_buffer_page(eb, i); |
3286 | if (page) | 3300 | if (page) |
@@ -3340,7 +3354,8 @@ int extent_range_uptodate(struct extent_io_tree *tree, | |||
3340 | } | 3354 | } |
3341 | 3355 | ||
3342 | int extent_buffer_uptodate(struct extent_io_tree *tree, | 3356 | int extent_buffer_uptodate(struct extent_io_tree *tree, |
3343 | struct extent_buffer *eb) | 3357 | struct extent_buffer *eb, |
3358 | struct extent_state *cached_state) | ||
3344 | { | 3359 | { |
3345 | int ret = 0; | 3360 | int ret = 0; |
3346 | unsigned long num_pages; | 3361 | unsigned long num_pages; |
@@ -3352,7 +3367,7 @@ int extent_buffer_uptodate(struct extent_io_tree *tree, | |||
3352 | return 1; | 3367 | return 1; |
3353 | 3368 | ||
3354 | ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1, | 3369 | ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1, |
3355 | EXTENT_UPTODATE, 1, NULL); | 3370 | EXTENT_UPTODATE, 1, cached_state); |
3356 | if (ret) | 3371 | if (ret) |
3357 | return ret; | 3372 | return ret; |
3358 | 3373 | ||
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 36de250a7b2b..bbab4813646f 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -163,6 +163,8 @@ int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask); | |||
163 | int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, | 163 | int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, |
164 | int bits, struct extent_state **cached, gfp_t mask); | 164 | int bits, struct extent_state **cached, gfp_t mask); |
165 | int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask); | 165 | int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask); |
166 | int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end, | ||
167 | struct extent_state **cached, gfp_t mask); | ||
166 | int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end, | 168 | int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end, |
167 | gfp_t mask); | 169 | gfp_t mask); |
168 | int extent_read_full_page(struct extent_io_tree *tree, struct page *page, | 170 | int extent_read_full_page(struct extent_io_tree *tree, struct page *page, |
@@ -196,7 +198,7 @@ int clear_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end, | |||
196 | int clear_extent_ordered_metadata(struct extent_io_tree *tree, u64 start, | 198 | int clear_extent_ordered_metadata(struct extent_io_tree *tree, u64 start, |
197 | u64 end, gfp_t mask); | 199 | u64 end, gfp_t mask); |
198 | int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, | 200 | int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, |
199 | gfp_t mask); | 201 | struct extent_state **cached_state, gfp_t mask); |
200 | int set_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end, | 202 | int set_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end, |
201 | gfp_t mask); | 203 | gfp_t mask); |
202 | int find_first_extent_bit(struct extent_io_tree *tree, u64 start, | 204 | int find_first_extent_bit(struct extent_io_tree *tree, u64 start, |
@@ -281,9 +283,11 @@ int test_extent_buffer_dirty(struct extent_io_tree *tree, | |||
281 | int set_extent_buffer_uptodate(struct extent_io_tree *tree, | 283 | int set_extent_buffer_uptodate(struct extent_io_tree *tree, |
282 | struct extent_buffer *eb); | 284 | struct extent_buffer *eb); |
283 | int clear_extent_buffer_uptodate(struct extent_io_tree *tree, | 285 | int clear_extent_buffer_uptodate(struct extent_io_tree *tree, |
284 | struct extent_buffer *eb); | 286 | struct extent_buffer *eb, |
287 | struct extent_state **cached_state); | ||
285 | int extent_buffer_uptodate(struct extent_io_tree *tree, | 288 | int extent_buffer_uptodate(struct extent_io_tree *tree, |
286 | struct extent_buffer *eb); | 289 | struct extent_buffer *eb, |
290 | struct extent_state *cached_state); | ||
287 | int map_extent_buffer(struct extent_buffer *eb, unsigned long offset, | 291 | int map_extent_buffer(struct extent_buffer *eb, unsigned long offset, |
288 | unsigned long min_len, char **token, char **map, | 292 | unsigned long min_len, char **token, char **map, |
289 | unsigned long *map_start, | 293 | unsigned long *map_start, |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index a7fd9f3a750a..d146dde7efb6 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -123,7 +123,8 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
123 | root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | 123 | root->sectorsize - 1) & ~((u64)root->sectorsize - 1); |
124 | 124 | ||
125 | end_of_last_block = start_pos + num_bytes - 1; | 125 | end_of_last_block = start_pos + num_bytes - 1; |
126 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block); | 126 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, |
127 | NULL); | ||
127 | if (err) | 128 | if (err) |
128 | return err; | 129 | return err; |
129 | 130 | ||
@@ -753,6 +754,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, | |||
753 | loff_t pos, unsigned long first_index, | 754 | loff_t pos, unsigned long first_index, |
754 | unsigned long last_index, size_t write_bytes) | 755 | unsigned long last_index, size_t write_bytes) |
755 | { | 756 | { |
757 | struct extent_state *cached_state = NULL; | ||
756 | int i; | 758 | int i; |
757 | unsigned long index = pos >> PAGE_CACHE_SHIFT; | 759 | unsigned long index = pos >> PAGE_CACHE_SHIFT; |
758 | struct inode *inode = fdentry(file)->d_inode; | 760 | struct inode *inode = fdentry(file)->d_inode; |
@@ -781,16 +783,18 @@ again: | |||
781 | } | 783 | } |
782 | if (start_pos < inode->i_size) { | 784 | if (start_pos < inode->i_size) { |
783 | struct btrfs_ordered_extent *ordered; | 785 | struct btrfs_ordered_extent *ordered; |
784 | lock_extent(&BTRFS_I(inode)->io_tree, | 786 | lock_extent_bits(&BTRFS_I(inode)->io_tree, |
785 | start_pos, last_pos - 1, GFP_NOFS); | 787 | start_pos, last_pos - 1, 0, &cached_state, |
788 | GFP_NOFS); | ||
786 | ordered = btrfs_lookup_first_ordered_extent(inode, | 789 | ordered = btrfs_lookup_first_ordered_extent(inode, |
787 | last_pos - 1); | 790 | last_pos - 1); |
788 | if (ordered && | 791 | if (ordered && |
789 | ordered->file_offset + ordered->len > start_pos && | 792 | ordered->file_offset + ordered->len > start_pos && |
790 | ordered->file_offset < last_pos) { | 793 | ordered->file_offset < last_pos) { |
791 | btrfs_put_ordered_extent(ordered); | 794 | btrfs_put_ordered_extent(ordered); |
792 | unlock_extent(&BTRFS_I(inode)->io_tree, | 795 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, |
793 | start_pos, last_pos - 1, GFP_NOFS); | 796 | start_pos, last_pos - 1, |
797 | &cached_state, GFP_NOFS); | ||
794 | for (i = 0; i < num_pages; i++) { | 798 | for (i = 0; i < num_pages; i++) { |
795 | unlock_page(pages[i]); | 799 | unlock_page(pages[i]); |
796 | page_cache_release(pages[i]); | 800 | page_cache_release(pages[i]); |
@@ -802,12 +806,13 @@ again: | |||
802 | if (ordered) | 806 | if (ordered) |
803 | btrfs_put_ordered_extent(ordered); | 807 | btrfs_put_ordered_extent(ordered); |
804 | 808 | ||
805 | clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos, | 809 | clear_extent_bit(&BTRFS_I(inode)->io_tree, start_pos, |
806 | last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC | | 810 | last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC | |
807 | EXTENT_DO_ACCOUNTING, | 811 | EXTENT_DO_ACCOUNTING, 0, 0, &cached_state, |
808 | GFP_NOFS); | 812 | GFP_NOFS); |
809 | unlock_extent(&BTRFS_I(inode)->io_tree, | 813 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, |
810 | start_pos, last_pos - 1, GFP_NOFS); | 814 | start_pos, last_pos - 1, &cached_state, |
815 | GFP_NOFS); | ||
811 | } | 816 | } |
812 | for (i = 0; i < num_pages; i++) { | 817 | for (i = 0; i < num_pages; i++) { |
813 | clear_page_dirty_for_io(pages[i]); | 818 | clear_page_dirty_for_io(pages[i]); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 1824dda1d351..2a337a09c650 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -573,8 +573,8 @@ retry: | |||
573 | unsigned long nr_written = 0; | 573 | unsigned long nr_written = 0; |
574 | 574 | ||
575 | lock_extent(io_tree, async_extent->start, | 575 | lock_extent(io_tree, async_extent->start, |
576 | async_extent->start + | 576 | async_extent->start + |
577 | async_extent->ram_size - 1, GFP_NOFS); | 577 | async_extent->ram_size - 1, GFP_NOFS); |
578 | 578 | ||
579 | /* allocate blocks */ | 579 | /* allocate blocks */ |
580 | ret = cow_file_range(inode, async_cow->locked_page, | 580 | ret = cow_file_range(inode, async_cow->locked_page, |
@@ -1512,12 +1512,13 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans, | |||
1512 | return 0; | 1512 | return 0; |
1513 | } | 1513 | } |
1514 | 1514 | ||
1515 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end) | 1515 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, |
1516 | struct extent_state **cached_state) | ||
1516 | { | 1517 | { |
1517 | if ((end & (PAGE_CACHE_SIZE - 1)) == 0) | 1518 | if ((end & (PAGE_CACHE_SIZE - 1)) == 0) |
1518 | WARN_ON(1); | 1519 | WARN_ON(1); |
1519 | return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end, | 1520 | return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end, |
1520 | GFP_NOFS); | 1521 | cached_state, GFP_NOFS); |
1521 | } | 1522 | } |
1522 | 1523 | ||
1523 | /* see btrfs_writepage_start_hook for details on why this is required */ | 1524 | /* see btrfs_writepage_start_hook for details on why this is required */ |
@@ -1530,6 +1531,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) | |||
1530 | { | 1531 | { |
1531 | struct btrfs_writepage_fixup *fixup; | 1532 | struct btrfs_writepage_fixup *fixup; |
1532 | struct btrfs_ordered_extent *ordered; | 1533 | struct btrfs_ordered_extent *ordered; |
1534 | struct extent_state *cached_state = NULL; | ||
1533 | struct page *page; | 1535 | struct page *page; |
1534 | struct inode *inode; | 1536 | struct inode *inode; |
1535 | u64 page_start; | 1537 | u64 page_start; |
@@ -1548,7 +1550,8 @@ again: | |||
1548 | page_start = page_offset(page); | 1550 | page_start = page_offset(page); |
1549 | page_end = page_offset(page) + PAGE_CACHE_SIZE - 1; | 1551 | page_end = page_offset(page) + PAGE_CACHE_SIZE - 1; |
1550 | 1552 | ||
1551 | lock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS); | 1553 | lock_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, 0, |
1554 | &cached_state, GFP_NOFS); | ||
1552 | 1555 | ||
1553 | /* already ordered? We're done */ | 1556 | /* already ordered? We're done */ |
1554 | if (PagePrivate2(page)) | 1557 | if (PagePrivate2(page)) |
@@ -1556,17 +1559,18 @@ again: | |||
1556 | 1559 | ||
1557 | ordered = btrfs_lookup_ordered_extent(inode, page_start); | 1560 | ordered = btrfs_lookup_ordered_extent(inode, page_start); |
1558 | if (ordered) { | 1561 | if (ordered) { |
1559 | unlock_extent(&BTRFS_I(inode)->io_tree, page_start, | 1562 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, |
1560 | page_end, GFP_NOFS); | 1563 | page_end, &cached_state, GFP_NOFS); |
1561 | unlock_page(page); | 1564 | unlock_page(page); |
1562 | btrfs_start_ordered_extent(inode, ordered, 1); | 1565 | btrfs_start_ordered_extent(inode, ordered, 1); |
1563 | goto again; | 1566 | goto again; |
1564 | } | 1567 | } |
1565 | 1568 | ||
1566 | btrfs_set_extent_delalloc(inode, page_start, page_end); | 1569 | btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state); |
1567 | ClearPageChecked(page); | 1570 | ClearPageChecked(page); |
1568 | out: | 1571 | out: |
1569 | unlock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS); | 1572 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end, |
1573 | &cached_state, GFP_NOFS); | ||
1570 | out_page: | 1574 | out_page: |
1571 | unlock_page(page); | 1575 | unlock_page(page); |
1572 | page_cache_release(page); | 1576 | page_cache_release(page); |
@@ -1695,6 +1699,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1695 | struct btrfs_trans_handle *trans; | 1699 | struct btrfs_trans_handle *trans; |
1696 | struct btrfs_ordered_extent *ordered_extent = NULL; | 1700 | struct btrfs_ordered_extent *ordered_extent = NULL; |
1697 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 1701 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
1702 | struct extent_state *cached_state = NULL; | ||
1698 | int compressed = 0; | 1703 | int compressed = 0; |
1699 | int ret; | 1704 | int ret; |
1700 | 1705 | ||
@@ -1716,9 +1721,9 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1716 | goto out; | 1721 | goto out; |
1717 | } | 1722 | } |
1718 | 1723 | ||
1719 | lock_extent(io_tree, ordered_extent->file_offset, | 1724 | lock_extent_bits(io_tree, ordered_extent->file_offset, |
1720 | ordered_extent->file_offset + ordered_extent->len - 1, | 1725 | ordered_extent->file_offset + ordered_extent->len - 1, |
1721 | GFP_NOFS); | 1726 | 0, &cached_state, GFP_NOFS); |
1722 | 1727 | ||
1723 | trans = btrfs_join_transaction(root, 1); | 1728 | trans = btrfs_join_transaction(root, 1); |
1724 | 1729 | ||
@@ -1745,9 +1750,10 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1745 | ordered_extent->len); | 1750 | ordered_extent->len); |
1746 | BUG_ON(ret); | 1751 | BUG_ON(ret); |
1747 | } | 1752 | } |
1748 | unlock_extent(io_tree, ordered_extent->file_offset, | 1753 | unlock_extent_cached(io_tree, ordered_extent->file_offset, |
1749 | ordered_extent->file_offset + ordered_extent->len - 1, | 1754 | ordered_extent->file_offset + |
1750 | GFP_NOFS); | 1755 | ordered_extent->len - 1, &cached_state, GFP_NOFS); |
1756 | |||
1751 | add_pending_csums(trans, inode, ordered_extent->file_offset, | 1757 | add_pending_csums(trans, inode, ordered_extent->file_offset, |
1752 | &ordered_extent->list); | 1758 | &ordered_extent->list); |
1753 | 1759 | ||
@@ -3084,6 +3090,7 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) | |||
3084 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3090 | struct btrfs_root *root = BTRFS_I(inode)->root; |
3085 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 3091 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
3086 | struct btrfs_ordered_extent *ordered; | 3092 | struct btrfs_ordered_extent *ordered; |
3093 | struct extent_state *cached_state = NULL; | ||
3087 | char *kaddr; | 3094 | char *kaddr; |
3088 | u32 blocksize = root->sectorsize; | 3095 | u32 blocksize = root->sectorsize; |
3089 | pgoff_t index = from >> PAGE_CACHE_SHIFT; | 3096 | pgoff_t index = from >> PAGE_CACHE_SHIFT; |
@@ -3130,12 +3137,14 @@ again: | |||
3130 | } | 3137 | } |
3131 | wait_on_page_writeback(page); | 3138 | wait_on_page_writeback(page); |
3132 | 3139 | ||
3133 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); | 3140 | lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state, |
3141 | GFP_NOFS); | ||
3134 | set_page_extent_mapped(page); | 3142 | set_page_extent_mapped(page); |
3135 | 3143 | ||
3136 | ordered = btrfs_lookup_ordered_extent(inode, page_start); | 3144 | ordered = btrfs_lookup_ordered_extent(inode, page_start); |
3137 | if (ordered) { | 3145 | if (ordered) { |
3138 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 3146 | unlock_extent_cached(io_tree, page_start, page_end, |
3147 | &cached_state, GFP_NOFS); | ||
3139 | unlock_page(page); | 3148 | unlock_page(page); |
3140 | page_cache_release(page); | 3149 | page_cache_release(page); |
3141 | btrfs_start_ordered_extent(inode, ordered, 1); | 3150 | btrfs_start_ordered_extent(inode, ordered, 1); |
@@ -3143,13 +3152,15 @@ again: | |||
3143 | goto again; | 3152 | goto again; |
3144 | } | 3153 | } |
3145 | 3154 | ||
3146 | clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, | 3155 | clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end, |
3147 | EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, | 3156 | EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, |
3148 | GFP_NOFS); | 3157 | 0, 0, &cached_state, GFP_NOFS); |
3149 | 3158 | ||
3150 | ret = btrfs_set_extent_delalloc(inode, page_start, page_end); | 3159 | ret = btrfs_set_extent_delalloc(inode, page_start, page_end, |
3160 | &cached_state); | ||
3151 | if (ret) { | 3161 | if (ret) { |
3152 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 3162 | unlock_extent_cached(io_tree, page_start, page_end, |
3163 | &cached_state, GFP_NOFS); | ||
3153 | goto out_unlock; | 3164 | goto out_unlock; |
3154 | } | 3165 | } |
3155 | 3166 | ||
@@ -3162,7 +3173,8 @@ again: | |||
3162 | } | 3173 | } |
3163 | ClearPageChecked(page); | 3174 | ClearPageChecked(page); |
3164 | set_page_dirty(page); | 3175 | set_page_dirty(page); |
3165 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 3176 | unlock_extent_cached(io_tree, page_start, page_end, &cached_state, |
3177 | GFP_NOFS); | ||
3166 | 3178 | ||
3167 | out_unlock: | 3179 | out_unlock: |
3168 | if (ret) | 3180 | if (ret) |
@@ -3180,6 +3192,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) | |||
3180 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3192 | struct btrfs_root *root = BTRFS_I(inode)->root; |
3181 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 3193 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
3182 | struct extent_map *em; | 3194 | struct extent_map *em; |
3195 | struct extent_state *cached_state = NULL; | ||
3183 | u64 mask = root->sectorsize - 1; | 3196 | u64 mask = root->sectorsize - 1; |
3184 | u64 hole_start = (inode->i_size + mask) & ~mask; | 3197 | u64 hole_start = (inode->i_size + mask) & ~mask; |
3185 | u64 block_end = (size + mask) & ~mask; | 3198 | u64 block_end = (size + mask) & ~mask; |
@@ -3195,11 +3208,13 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) | |||
3195 | struct btrfs_ordered_extent *ordered; | 3208 | struct btrfs_ordered_extent *ordered; |
3196 | btrfs_wait_ordered_range(inode, hole_start, | 3209 | btrfs_wait_ordered_range(inode, hole_start, |
3197 | block_end - hole_start); | 3210 | block_end - hole_start); |
3198 | lock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS); | 3211 | lock_extent_bits(io_tree, hole_start, block_end - 1, 0, |
3212 | &cached_state, GFP_NOFS); | ||
3199 | ordered = btrfs_lookup_ordered_extent(inode, hole_start); | 3213 | ordered = btrfs_lookup_ordered_extent(inode, hole_start); |
3200 | if (!ordered) | 3214 | if (!ordered) |
3201 | break; | 3215 | break; |
3202 | unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS); | 3216 | unlock_extent_cached(io_tree, hole_start, block_end - 1, |
3217 | &cached_state, GFP_NOFS); | ||
3203 | btrfs_put_ordered_extent(ordered); | 3218 | btrfs_put_ordered_extent(ordered); |
3204 | } | 3219 | } |
3205 | 3220 | ||
@@ -3244,7 +3259,8 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) | |||
3244 | break; | 3259 | break; |
3245 | } | 3260 | } |
3246 | 3261 | ||
3247 | unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS); | 3262 | unlock_extent_cached(io_tree, hole_start, block_end - 1, &cached_state, |
3263 | GFP_NOFS); | ||
3248 | return err; | 3264 | return err; |
3249 | } | 3265 | } |
3250 | 3266 | ||
@@ -4985,6 +5001,7 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) | |||
4985 | { | 5001 | { |
4986 | struct extent_io_tree *tree; | 5002 | struct extent_io_tree *tree; |
4987 | struct btrfs_ordered_extent *ordered; | 5003 | struct btrfs_ordered_extent *ordered; |
5004 | struct extent_state *cached_state = NULL; | ||
4988 | u64 page_start = page_offset(page); | 5005 | u64 page_start = page_offset(page); |
4989 | u64 page_end = page_start + PAGE_CACHE_SIZE - 1; | 5006 | u64 page_end = page_start + PAGE_CACHE_SIZE - 1; |
4990 | 5007 | ||
@@ -5003,7 +5020,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) | |||
5003 | btrfs_releasepage(page, GFP_NOFS); | 5020 | btrfs_releasepage(page, GFP_NOFS); |
5004 | return; | 5021 | return; |
5005 | } | 5022 | } |
5006 | lock_extent(tree, page_start, page_end, GFP_NOFS); | 5023 | lock_extent_bits(tree, page_start, page_end, 0, &cached_state, |
5024 | GFP_NOFS); | ||
5007 | ordered = btrfs_lookup_ordered_extent(page->mapping->host, | 5025 | ordered = btrfs_lookup_ordered_extent(page->mapping->host, |
5008 | page_offset(page)); | 5026 | page_offset(page)); |
5009 | if (ordered) { | 5027 | if (ordered) { |
@@ -5014,7 +5032,7 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) | |||
5014 | clear_extent_bit(tree, page_start, page_end, | 5032 | clear_extent_bit(tree, page_start, page_end, |
5015 | EXTENT_DIRTY | EXTENT_DELALLOC | | 5033 | EXTENT_DIRTY | EXTENT_DELALLOC | |
5016 | EXTENT_LOCKED | EXTENT_DO_ACCOUNTING, 1, 0, | 5034 | EXTENT_LOCKED | EXTENT_DO_ACCOUNTING, 1, 0, |
5017 | NULL, GFP_NOFS); | 5035 | &cached_state, GFP_NOFS); |
5018 | /* | 5036 | /* |
5019 | * whoever cleared the private bit is responsible | 5037 | * whoever cleared the private bit is responsible |
5020 | * for the finish_ordered_io | 5038 | * for the finish_ordered_io |
@@ -5024,11 +5042,13 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) | |||
5024 | page_start, page_end); | 5042 | page_start, page_end); |
5025 | } | 5043 | } |
5026 | btrfs_put_ordered_extent(ordered); | 5044 | btrfs_put_ordered_extent(ordered); |
5027 | lock_extent(tree, page_start, page_end, GFP_NOFS); | 5045 | cached_state = NULL; |
5046 | lock_extent_bits(tree, page_start, page_end, 0, &cached_state, | ||
5047 | GFP_NOFS); | ||
5028 | } | 5048 | } |
5029 | clear_extent_bit(tree, page_start, page_end, | 5049 | clear_extent_bit(tree, page_start, page_end, |
5030 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | | 5050 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | |
5031 | EXTENT_DO_ACCOUNTING, 1, 1, NULL, GFP_NOFS); | 5051 | EXTENT_DO_ACCOUNTING, 1, 1, &cached_state, GFP_NOFS); |
5032 | __btrfs_releasepage(page, GFP_NOFS); | 5052 | __btrfs_releasepage(page, GFP_NOFS); |
5033 | 5053 | ||
5034 | ClearPageChecked(page); | 5054 | ClearPageChecked(page); |
@@ -5061,6 +5081,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
5061 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5081 | struct btrfs_root *root = BTRFS_I(inode)->root; |
5062 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 5082 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
5063 | struct btrfs_ordered_extent *ordered; | 5083 | struct btrfs_ordered_extent *ordered; |
5084 | struct extent_state *cached_state = NULL; | ||
5064 | char *kaddr; | 5085 | char *kaddr; |
5065 | unsigned long zero_start; | 5086 | unsigned long zero_start; |
5066 | loff_t size; | 5087 | loff_t size; |
@@ -5099,7 +5120,8 @@ again: | |||
5099 | } | 5120 | } |
5100 | wait_on_page_writeback(page); | 5121 | wait_on_page_writeback(page); |
5101 | 5122 | ||
5102 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); | 5123 | lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state, |
5124 | GFP_NOFS); | ||
5103 | set_page_extent_mapped(page); | 5125 | set_page_extent_mapped(page); |
5104 | 5126 | ||
5105 | /* | 5127 | /* |
@@ -5108,7 +5130,8 @@ again: | |||
5108 | */ | 5130 | */ |
5109 | ordered = btrfs_lookup_ordered_extent(inode, page_start); | 5131 | ordered = btrfs_lookup_ordered_extent(inode, page_start); |
5110 | if (ordered) { | 5132 | if (ordered) { |
5111 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 5133 | unlock_extent_cached(io_tree, page_start, page_end, |
5134 | &cached_state, GFP_NOFS); | ||
5112 | unlock_page(page); | 5135 | unlock_page(page); |
5113 | btrfs_start_ordered_extent(inode, ordered, 1); | 5136 | btrfs_start_ordered_extent(inode, ordered, 1); |
5114 | btrfs_put_ordered_extent(ordered); | 5137 | btrfs_put_ordered_extent(ordered); |
@@ -5122,13 +5145,15 @@ again: | |||
5122 | * is probably a better way to do this, but for now keep consistent with | 5145 | * is probably a better way to do this, but for now keep consistent with |
5123 | * prepare_pages in the normal write path. | 5146 | * prepare_pages in the normal write path. |
5124 | */ | 5147 | */ |
5125 | clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, | 5148 | clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end, |
5126 | EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, | 5149 | EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, |
5127 | GFP_NOFS); | 5150 | 0, 0, &cached_state, GFP_NOFS); |
5128 | 5151 | ||
5129 | ret = btrfs_set_extent_delalloc(inode, page_start, page_end); | 5152 | ret = btrfs_set_extent_delalloc(inode, page_start, page_end, |
5153 | &cached_state); | ||
5130 | if (ret) { | 5154 | if (ret) { |
5131 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 5155 | unlock_extent_cached(io_tree, page_start, page_end, |
5156 | &cached_state, GFP_NOFS); | ||
5132 | ret = VM_FAULT_SIGBUS; | 5157 | ret = VM_FAULT_SIGBUS; |
5133 | btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); | 5158 | btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); |
5134 | goto out_unlock; | 5159 | goto out_unlock; |
@@ -5154,7 +5179,7 @@ again: | |||
5154 | BTRFS_I(inode)->last_trans = root->fs_info->generation; | 5179 | BTRFS_I(inode)->last_trans = root->fs_info->generation; |
5155 | BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid; | 5180 | BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid; |
5156 | 5181 | ||
5157 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 5182 | unlock_extent_cached(io_tree, page_start, page_end, &cached_state, GFP_NOFS); |
5158 | 5183 | ||
5159 | out_unlock: | 5184 | out_unlock: |
5160 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | 5185 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); |
@@ -5833,6 +5858,7 @@ stop_trans: | |||
5833 | static long btrfs_fallocate(struct inode *inode, int mode, | 5858 | static long btrfs_fallocate(struct inode *inode, int mode, |
5834 | loff_t offset, loff_t len) | 5859 | loff_t offset, loff_t len) |
5835 | { | 5860 | { |
5861 | struct extent_state *cached_state = NULL; | ||
5836 | u64 cur_offset; | 5862 | u64 cur_offset; |
5837 | u64 last_byte; | 5863 | u64 last_byte; |
5838 | u64 alloc_start; | 5864 | u64 alloc_start; |
@@ -5871,16 +5897,17 @@ static long btrfs_fallocate(struct inode *inode, int mode, | |||
5871 | /* the extent lock is ordered inside the running | 5897 | /* the extent lock is ordered inside the running |
5872 | * transaction | 5898 | * transaction |
5873 | */ | 5899 | */ |
5874 | lock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, | 5900 | lock_extent_bits(&BTRFS_I(inode)->io_tree, alloc_start, |
5875 | GFP_NOFS); | 5901 | locked_end, 0, &cached_state, GFP_NOFS); |
5876 | ordered = btrfs_lookup_first_ordered_extent(inode, | 5902 | ordered = btrfs_lookup_first_ordered_extent(inode, |
5877 | alloc_end - 1); | 5903 | alloc_end - 1); |
5878 | if (ordered && | 5904 | if (ordered && |
5879 | ordered->file_offset + ordered->len > alloc_start && | 5905 | ordered->file_offset + ordered->len > alloc_start && |
5880 | ordered->file_offset < alloc_end) { | 5906 | ordered->file_offset < alloc_end) { |
5881 | btrfs_put_ordered_extent(ordered); | 5907 | btrfs_put_ordered_extent(ordered); |
5882 | unlock_extent(&BTRFS_I(inode)->io_tree, | 5908 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, |
5883 | alloc_start, locked_end, GFP_NOFS); | 5909 | alloc_start, locked_end, |
5910 | &cached_state, GFP_NOFS); | ||
5884 | /* | 5911 | /* |
5885 | * we can't wait on the range with the transaction | 5912 | * we can't wait on the range with the transaction |
5886 | * running or with the extent lock held | 5913 | * running or with the extent lock held |
@@ -5922,8 +5949,8 @@ static long btrfs_fallocate(struct inode *inode, int mode, | |||
5922 | break; | 5949 | break; |
5923 | } | 5950 | } |
5924 | } | 5951 | } |
5925 | unlock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, | 5952 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, |
5926 | GFP_NOFS); | 5953 | &cached_state, GFP_NOFS); |
5927 | 5954 | ||
5928 | btrfs_free_reserved_data_space(BTRFS_I(inode)->root, inode, | 5955 | btrfs_free_reserved_data_space(BTRFS_I(inode)->root, inode, |
5929 | alloc_end - alloc_start); | 5956 | alloc_end - alloc_start); |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index d866b460c26e..9aaba6e472d3 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -673,7 +673,7 @@ again: | |||
673 | page_end, EXTENT_DIRTY | EXTENT_DELALLOC | | 673 | page_end, EXTENT_DIRTY | EXTENT_DELALLOC | |
674 | EXTENT_DO_ACCOUNTING, GFP_NOFS); | 674 | EXTENT_DO_ACCOUNTING, GFP_NOFS); |
675 | 675 | ||
676 | btrfs_set_extent_delalloc(inode, page_start, page_end); | 676 | btrfs_set_extent_delalloc(inode, page_start, page_end, NULL); |
677 | ClearPageChecked(page); | 677 | ClearPageChecked(page); |
678 | set_page_dirty(page); | 678 | set_page_dirty(page); |
679 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 679 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index d52759daa53f..0b23942cbc0d 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -2659,7 +2659,7 @@ static int relocate_file_extent_cluster(struct inode *inode, | |||
2659 | EXTENT_BOUNDARY, GFP_NOFS); | 2659 | EXTENT_BOUNDARY, GFP_NOFS); |
2660 | nr++; | 2660 | nr++; |
2661 | } | 2661 | } |
2662 | btrfs_set_extent_delalloc(inode, page_start, page_end); | 2662 | btrfs_set_extent_delalloc(inode, page_start, page_end, NULL); |
2663 | 2663 | ||
2664 | set_page_dirty(page); | 2664 | set_page_dirty(page); |
2665 | dirty_page++; | 2665 | dirty_page++; |