aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent_io.c46
-rw-r--r--fs/btrfs/extent_io.h2
-rw-r--r--fs/btrfs/inode.c6
-rw-r--r--fs/btrfs/ordered-data.c8
-rw-r--r--fs/btrfs/relocation.c2
5 files changed, 40 insertions, 24 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 04fafc3cffc0..c9a438d374b6 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -720,6 +720,13 @@ again:
720 } 720 }
721 721
722 spin_lock(&tree->lock); 722 spin_lock(&tree->lock);
723 if (cached_state && *cached_state) {
724 state = *cached_state;
725 if (state->start == start && state->tree) {
726 node = &state->rb_node;
727 goto hit_next;
728 }
729 }
723 /* 730 /*
724 * this search will find all the extents that end after 731 * this search will find all the extents that end after
725 * our range starts. 732 * our range starts.
@@ -1286,6 +1293,7 @@ static noinline u64 find_lock_delalloc_range(struct inode *inode,
1286 u64 delalloc_start; 1293 u64 delalloc_start;
1287 u64 delalloc_end; 1294 u64 delalloc_end;
1288 u64 found; 1295 u64 found;
1296 struct extent_state *cached_state = NULL;
1289 int ret; 1297 int ret;
1290 int loops = 0; 1298 int loops = 0;
1291 1299
@@ -1323,6 +1331,7 @@ again:
1323 /* some of the pages are gone, lets avoid looping by 1331 /* some of the pages are gone, lets avoid looping by
1324 * shortening the size of the delalloc range we're searching 1332 * shortening the size of the delalloc range we're searching
1325 */ 1333 */
1334 free_extent_state(cached_state);
1326 if (!loops) { 1335 if (!loops) {
1327 unsigned long offset = (*start) & (PAGE_CACHE_SIZE - 1); 1336 unsigned long offset = (*start) & (PAGE_CACHE_SIZE - 1);
1328 max_bytes = PAGE_CACHE_SIZE - offset; 1337 max_bytes = PAGE_CACHE_SIZE - offset;
@@ -1336,18 +1345,21 @@ again:
1336 BUG_ON(ret); 1345 BUG_ON(ret);
1337 1346
1338 /* step three, lock the state bits for the whole range */ 1347 /* step three, lock the state bits for the whole range */
1339 lock_extent(tree, delalloc_start, delalloc_end, GFP_NOFS); 1348 lock_extent_bits(tree, delalloc_start, delalloc_end,
1349 0, &cached_state, GFP_NOFS);
1340 1350
1341 /* then test to make sure it is all still delalloc */ 1351 /* then test to make sure it is all still delalloc */
1342 ret = test_range_bit(tree, delalloc_start, delalloc_end, 1352 ret = test_range_bit(tree, delalloc_start, delalloc_end,
1343 EXTENT_DELALLOC, 1); 1353 EXTENT_DELALLOC, 1, cached_state);
1344 if (!ret) { 1354 if (!ret) {
1345 unlock_extent(tree, delalloc_start, delalloc_end, GFP_NOFS); 1355 unlock_extent_cached(tree, delalloc_start, delalloc_end,
1356 &cached_state, GFP_NOFS);
1346 __unlock_for_delalloc(inode, locked_page, 1357 __unlock_for_delalloc(inode, locked_page,
1347 delalloc_start, delalloc_end); 1358 delalloc_start, delalloc_end);
1348 cond_resched(); 1359 cond_resched();
1349 goto again; 1360 goto again;
1350 } 1361 }
1362 free_extent_state(cached_state);
1351 *start = delalloc_start; 1363 *start = delalloc_start;
1352 *end = delalloc_end; 1364 *end = delalloc_end;
1353out_failed: 1365out_failed:
@@ -1530,14 +1542,17 @@ out:
1530 * range is found set. 1542 * range is found set.
1531 */ 1543 */
1532int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end, 1544int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end,
1533 int bits, int filled) 1545 int bits, int filled, struct extent_state *cached)
1534{ 1546{
1535 struct extent_state *state = NULL; 1547 struct extent_state *state = NULL;
1536 struct rb_node *node; 1548 struct rb_node *node;
1537 int bitset = 0; 1549 int bitset = 0;
1538 1550
1539 spin_lock(&tree->lock); 1551 spin_lock(&tree->lock);
1540 node = tree_search(tree, start); 1552 if (cached && cached->tree && cached->start == start)
1553 node = &cached->rb_node;
1554 else
1555 node = tree_search(tree, start);
1541 while (node && start <= end) { 1556 while (node && start <= end) {
1542 state = rb_entry(node, struct extent_state, rb_node); 1557 state = rb_entry(node, struct extent_state, rb_node);
1543 1558
@@ -1580,7 +1595,7 @@ static int check_page_uptodate(struct extent_io_tree *tree,
1580{ 1595{
1581 u64 start = (u64)page->index << PAGE_CACHE_SHIFT; 1596 u64 start = (u64)page->index << PAGE_CACHE_SHIFT;
1582 u64 end = start + PAGE_CACHE_SIZE - 1; 1597 u64 end = start + PAGE_CACHE_SIZE - 1;
1583 if (test_range_bit(tree, start, end, EXTENT_UPTODATE, 1)) 1598 if (test_range_bit(tree, start, end, EXTENT_UPTODATE, 1, NULL))
1584 SetPageUptodate(page); 1599 SetPageUptodate(page);
1585 return 0; 1600 return 0;
1586} 1601}
@@ -1594,7 +1609,7 @@ static int check_page_locked(struct extent_io_tree *tree,
1594{ 1609{
1595 u64 start = (u64)page->index << PAGE_CACHE_SHIFT; 1610 u64 start = (u64)page->index << PAGE_CACHE_SHIFT;
1596 u64 end = start + PAGE_CACHE_SIZE - 1; 1611 u64 end = start + PAGE_CACHE_SIZE - 1;
1597 if (!test_range_bit(tree, start, end, EXTENT_LOCKED, 0)) 1612 if (!test_range_bit(tree, start, end, EXTENT_LOCKED, 0, NULL))
1598 unlock_page(page); 1613 unlock_page(page);
1599 return 0; 1614 return 0;
1600} 1615}
@@ -2032,7 +2047,8 @@ static int __extent_read_full_page(struct extent_io_tree *tree,
2032 continue; 2047 continue;
2033 } 2048 }
2034 /* the get_extent function already copied into the page */ 2049 /* the get_extent function already copied into the page */
2035 if (test_range_bit(tree, cur, cur_end, EXTENT_UPTODATE, 1)) { 2050 if (test_range_bit(tree, cur, cur_end,
2051 EXTENT_UPTODATE, 1, NULL)) {
2036 check_page_uptodate(tree, page); 2052 check_page_uptodate(tree, page);
2037 unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS); 2053 unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS);
2038 cur = cur + iosize; 2054 cur = cur + iosize;
@@ -2305,7 +2321,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
2305 } 2321 }
2306 /* leave this out until we have a page_mkwrite call */ 2322 /* leave this out until we have a page_mkwrite call */
2307 if (0 && !test_range_bit(tree, cur, cur + iosize - 1, 2323 if (0 && !test_range_bit(tree, cur, cur + iosize - 1,
2308 EXTENT_DIRTY, 0)) { 2324 EXTENT_DIRTY, 0, NULL)) {
2309 cur = cur + iosize; 2325 cur = cur + iosize;
2310 pg_offset += iosize; 2326 pg_offset += iosize;
2311 continue; 2327 continue;
@@ -2721,7 +2737,7 @@ int extent_prepare_write(struct extent_io_tree *tree,
2721 !isnew && !PageUptodate(page) && 2737 !isnew && !PageUptodate(page) &&
2722 (block_off_end > to || block_off_start < from) && 2738 (block_off_end > to || block_off_start < from) &&
2723 !test_range_bit(tree, block_start, cur_end, 2739 !test_range_bit(tree, block_start, cur_end,
2724 EXTENT_UPTODATE, 1)) { 2740 EXTENT_UPTODATE, 1, NULL)) {
2725 u64 sector; 2741 u64 sector;
2726 u64 extent_offset = block_start - em->start; 2742 u64 extent_offset = block_start - em->start;
2727 size_t iosize; 2743 size_t iosize;
@@ -2776,7 +2792,7 @@ int try_release_extent_state(struct extent_map_tree *map,
2776 int ret = 1; 2792 int ret = 1;
2777 2793
2778 if (test_range_bit(tree, start, end, 2794 if (test_range_bit(tree, start, end,
2779 EXTENT_IOBITS | EXTENT_ORDERED, 0)) 2795 EXTENT_IOBITS | EXTENT_ORDERED, 0, NULL))
2780 ret = 0; 2796 ret = 0;
2781 else { 2797 else {
2782 if ((mask & GFP_NOFS) == GFP_NOFS) 2798 if ((mask & GFP_NOFS) == GFP_NOFS)
@@ -2821,7 +2837,7 @@ int try_release_extent_mapping(struct extent_map_tree *map,
2821 extent_map_end(em) - 1, 2837 extent_map_end(em) - 1,
2822 EXTENT_LOCKED | EXTENT_WRITEBACK | 2838 EXTENT_LOCKED | EXTENT_WRITEBACK |
2823 EXTENT_ORDERED, 2839 EXTENT_ORDERED,
2824 0)) { 2840 0, NULL)) {
2825 remove_extent_mapping(map, em); 2841 remove_extent_mapping(map, em);
2826 /* once for the rb tree */ 2842 /* once for the rb tree */
2827 free_extent_map(em); 2843 free_extent_map(em);
@@ -3237,7 +3253,7 @@ int extent_range_uptodate(struct extent_io_tree *tree,
3237 int uptodate; 3253 int uptodate;
3238 unsigned long index; 3254 unsigned long index;
3239 3255
3240 ret = test_range_bit(tree, start, end, EXTENT_UPTODATE, 1); 3256 ret = test_range_bit(tree, start, end, EXTENT_UPTODATE, 1, NULL);
3241 if (ret) 3257 if (ret)
3242 return 1; 3258 return 1;
3243 while (start <= end) { 3259 while (start <= end) {
@@ -3267,7 +3283,7 @@ int extent_buffer_uptodate(struct extent_io_tree *tree,
3267 return 1; 3283 return 1;
3268 3284
3269 ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1, 3285 ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1,
3270 EXTENT_UPTODATE, 1); 3286 EXTENT_UPTODATE, 1, NULL);
3271 if (ret) 3287 if (ret)
3272 return ret; 3288 return ret;
3273 3289
@@ -3303,7 +3319,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
3303 return 0; 3319 return 0;
3304 3320
3305 if (test_range_bit(tree, eb->start, eb->start + eb->len - 1, 3321 if (test_range_bit(tree, eb->start, eb->start + eb->len - 1,
3306 EXTENT_UPTODATE, 1)) { 3322 EXTENT_UPTODATE, 1, NULL)) {
3307 return 0; 3323 return 0;
3308 } 3324 }
3309 3325
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index c8ead2b8c4c9..09cd6fa3cc86 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -157,7 +157,7 @@ u64 count_range_bits(struct extent_io_tree *tree,
157 u64 max_bytes, unsigned long bits); 157 u64 max_bytes, unsigned long bits);
158 158
159int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end, 159int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end,
160 int bits, int filled); 160 int bits, int filled, struct extent_state *cached_state);
161int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, 161int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
162 int bits, gfp_t mask); 162 int bits, gfp_t mask);
163int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, 163int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e494545c4202..3f8e93de2989 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1376,7 +1376,7 @@ again:
1376 1376
1377 /* already ordered? We're done */ 1377 /* already ordered? We're done */
1378 if (test_range_bit(&BTRFS_I(inode)->io_tree, page_start, page_end, 1378 if (test_range_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
1379 EXTENT_ORDERED, 0)) { 1379 EXTENT_ORDERED, 0, NULL)) {
1380 goto out; 1380 goto out;
1381 } 1381 }
1382 1382
@@ -1417,7 +1417,7 @@ static int btrfs_writepage_start_hook(struct page *page, u64 start, u64 end)
1417 int ret; 1417 int ret;
1418 1418
1419 ret = test_range_bit(&BTRFS_I(inode)->io_tree, start, end, 1419 ret = test_range_bit(&BTRFS_I(inode)->io_tree, start, end,
1420 EXTENT_ORDERED, 0); 1420 EXTENT_ORDERED, 0, NULL);
1421 if (ret) 1421 if (ret)
1422 return 0; 1422 return 0;
1423 1423
@@ -1795,7 +1795,7 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end,
1795 return 0; 1795 return 0;
1796 1796
1797 if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID && 1797 if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID &&
1798 test_range_bit(io_tree, start, end, EXTENT_NODATASUM, 1)) { 1798 test_range_bit(io_tree, start, end, EXTENT_NODATASUM, 1, NULL)) {
1799 clear_extent_bits(io_tree, start, end, EXTENT_NODATASUM, 1799 clear_extent_bits(io_tree, start, end, EXTENT_NODATASUM,
1800 GFP_NOFS); 1800 GFP_NOFS);
1801 return 0; 1801 return 0;
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index d6f0806c682f..7f751e462f0b 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -262,7 +262,7 @@ int btrfs_dec_test_ordered_pending(struct inode *inode,
262 262
263 ret = test_range_bit(io_tree, entry->file_offset, 263 ret = test_range_bit(io_tree, entry->file_offset,
264 entry->file_offset + entry->len - 1, 264 entry->file_offset + entry->len - 1,
265 EXTENT_ORDERED, 0); 265 EXTENT_ORDERED, 0, NULL);
266 if (ret == 0) 266 if (ret == 0)
267 ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags); 267 ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags);
268out: 268out:
@@ -522,7 +522,7 @@ again:
522 end--; 522 end--;
523 } 523 }
524 if (test_range_bit(&BTRFS_I(inode)->io_tree, start, orig_end, 524 if (test_range_bit(&BTRFS_I(inode)->io_tree, start, orig_end,
525 EXTENT_ORDERED | EXTENT_DELALLOC, 0)) { 525 EXTENT_ORDERED | EXTENT_DELALLOC, 0, NULL)) {
526 schedule_timeout(1); 526 schedule_timeout(1);
527 goto again; 527 goto again;
528 } 528 }
@@ -613,7 +613,7 @@ int btrfs_ordered_update_i_size(struct inode *inode,
613 */ 613 */
614 if (test_range_bit(io_tree, disk_i_size, 614 if (test_range_bit(io_tree, disk_i_size,
615 ordered->file_offset + ordered->len - 1, 615 ordered->file_offset + ordered->len - 1,
616 EXTENT_DELALLOC, 0)) { 616 EXTENT_DELALLOC, 0, NULL)) {
617 goto out; 617 goto out;
618 } 618 }
619 /* 619 /*
@@ -664,7 +664,7 @@ int btrfs_ordered_update_i_size(struct inode *inode,
664 */ 664 */
665 if (i_size_test > entry_end(ordered) && 665 if (i_size_test > entry_end(ordered) &&
666 !test_range_bit(io_tree, entry_end(ordered), i_size_test - 1, 666 !test_range_bit(io_tree, entry_end(ordered), i_size_test - 1,
667 EXTENT_DELALLOC, 0)) { 667 EXTENT_DELALLOC, 0, NULL)) {
668 new_i_size = min_t(u64, i_size_test, i_size_read(inode)); 668 new_i_size = min_t(u64, i_size_test, i_size_read(inode));
669 } 669 }
670 BTRFS_I(inode)->disk_i_size = new_i_size; 670 BTRFS_I(inode)->disk_i_size = new_i_size;
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 4adab903fc2b..3be16ccc7eea 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2180,7 +2180,7 @@ static int tree_block_processed(u64 bytenr, u32 blocksize,
2180 struct reloc_control *rc) 2180 struct reloc_control *rc)
2181{ 2181{
2182 if (test_range_bit(&rc->processed_blocks, bytenr, 2182 if (test_range_bit(&rc->processed_blocks, bytenr,
2183 bytenr + blocksize - 1, EXTENT_DIRTY, 1)) 2183 bytenr + blocksize - 1, EXTENT_DIRTY, 1, NULL))
2184 return 1; 2184 return 1;
2185 return 0; 2185 return 0;
2186} 2186}