aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/disk-io.c15
-rw-r--r--fs/btrfs/extent-tree.c11
-rw-r--r--fs/btrfs/extent_io.c61
-rw-r--r--fs/btrfs/extent_io.h10
-rw-r--r--fs/btrfs/file.c23
-rw-r--r--fs/btrfs/inode.c111
-rw-r--r--fs/btrfs/ioctl.c2
-rw-r--r--fs/btrfs/relocation.c2
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
2313int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); 2313int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput);
2314int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); 2314int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
2315 struct extent_state **cached_state);
2315int btrfs_writepages(struct address_space *mapping, 2316int btrfs_writepages(struct address_space *mapping,
2316 struct writeback_control *wbc); 2317 struct writeback_control *wbc);
2317int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, 2318int 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,
263static int verify_parent_transid(struct extent_io_tree *io_tree, 263static 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);
286out: 288out:
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;
517again: 520again:
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
948int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, 957int 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
956int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, 965int 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
986static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, 995static 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
993int wait_on_extent_writeback(struct extent_io_tree *tree, u64 start, u64 end) 1003int 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