diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent_io.c | 27 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 16 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 45 |
3 files changed, 51 insertions, 37 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index de1793ba004a..f9708bd01669 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -1401,12 +1401,7 @@ out_failed: | |||
1401 | int extent_clear_unlock_delalloc(struct inode *inode, | 1401 | int extent_clear_unlock_delalloc(struct inode *inode, |
1402 | struct extent_io_tree *tree, | 1402 | struct extent_io_tree *tree, |
1403 | u64 start, u64 end, struct page *locked_page, | 1403 | u64 start, u64 end, struct page *locked_page, |
1404 | int unlock_pages, | 1404 | unsigned long op) |
1405 | int clear_unlock, | ||
1406 | int clear_delalloc, int clear_dirty, | ||
1407 | int set_writeback, | ||
1408 | int end_writeback, | ||
1409 | int set_private2) | ||
1410 | { | 1405 | { |
1411 | int ret; | 1406 | int ret; |
1412 | struct page *pages[16]; | 1407 | struct page *pages[16]; |
@@ -1416,17 +1411,17 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
1416 | int i; | 1411 | int i; |
1417 | int clear_bits = 0; | 1412 | int clear_bits = 0; |
1418 | 1413 | ||
1419 | if (clear_unlock) | 1414 | if (op & EXTENT_CLEAR_UNLOCK) |
1420 | clear_bits |= EXTENT_LOCKED; | 1415 | clear_bits |= EXTENT_LOCKED; |
1421 | if (clear_dirty) | 1416 | if (op & EXTENT_CLEAR_DIRTY) |
1422 | clear_bits |= EXTENT_DIRTY; | 1417 | clear_bits |= EXTENT_DIRTY; |
1423 | 1418 | ||
1424 | if (clear_delalloc) | 1419 | if (op & EXTENT_CLEAR_DELALLOC) |
1425 | clear_bits |= EXTENT_DELALLOC; | 1420 | clear_bits |= EXTENT_DELALLOC; |
1426 | 1421 | ||
1427 | clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS); | 1422 | clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS); |
1428 | if (!(unlock_pages || clear_dirty || set_writeback || end_writeback || | 1423 | if (!(op & (EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY | EXTENT_SET_WRITEBACK | |
1429 | set_private2)) | 1424 | EXTENT_END_WRITEBACK | EXTENT_SET_PRIVATE2))) |
1430 | return 0; | 1425 | return 0; |
1431 | 1426 | ||
1432 | while (nr_pages > 0) { | 1427 | while (nr_pages > 0) { |
@@ -1435,20 +1430,20 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
1435 | nr_pages, ARRAY_SIZE(pages)), pages); | 1430 | nr_pages, ARRAY_SIZE(pages)), pages); |
1436 | for (i = 0; i < ret; i++) { | 1431 | for (i = 0; i < ret; i++) { |
1437 | 1432 | ||
1438 | if (set_private2) | 1433 | if (op & EXTENT_SET_PRIVATE2) |
1439 | SetPagePrivate2(pages[i]); | 1434 | SetPagePrivate2(pages[i]); |
1440 | 1435 | ||
1441 | if (pages[i] == locked_page) { | 1436 | if (pages[i] == locked_page) { |
1442 | page_cache_release(pages[i]); | 1437 | page_cache_release(pages[i]); |
1443 | continue; | 1438 | continue; |
1444 | } | 1439 | } |
1445 | if (clear_dirty) | 1440 | if (op & EXTENT_CLEAR_DIRTY) |
1446 | clear_page_dirty_for_io(pages[i]); | 1441 | clear_page_dirty_for_io(pages[i]); |
1447 | if (set_writeback) | 1442 | if (op & EXTENT_SET_WRITEBACK) |
1448 | set_page_writeback(pages[i]); | 1443 | set_page_writeback(pages[i]); |
1449 | if (end_writeback) | 1444 | if (op & EXTENT_END_WRITEBACK) |
1450 | end_page_writeback(pages[i]); | 1445 | end_page_writeback(pages[i]); |
1451 | if (unlock_pages) | 1446 | if (op & EXTENT_CLEAR_UNLOCK_PAGE) |
1452 | unlock_page(pages[i]); | 1447 | unlock_page(pages[i]); |
1453 | page_cache_release(pages[i]); | 1448 | page_cache_release(pages[i]); |
1454 | } | 1449 | } |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 4794ec891fed..41d2a47ecf38 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -25,6 +25,15 @@ | |||
25 | #define EXTENT_BUFFER_BLOCKING 1 | 25 | #define EXTENT_BUFFER_BLOCKING 1 |
26 | #define EXTENT_BUFFER_DIRTY 2 | 26 | #define EXTENT_BUFFER_DIRTY 2 |
27 | 27 | ||
28 | /* these are flags for extent_clear_unlock_delalloc */ | ||
29 | #define EXTENT_CLEAR_UNLOCK_PAGE 0x1 | ||
30 | #define EXTENT_CLEAR_UNLOCK 0x2 | ||
31 | #define EXTENT_CLEAR_DELALLOC 0x4 | ||
32 | #define EXTENT_CLEAR_DIRTY 0x8 | ||
33 | #define EXTENT_SET_WRITEBACK 0x10 | ||
34 | #define EXTENT_END_WRITEBACK 0x20 | ||
35 | #define EXTENT_SET_PRIVATE2 0x40 | ||
36 | |||
28 | /* | 37 | /* |
29 | * page->private values. Every page that is controlled by the extent | 38 | * page->private values. Every page that is controlled by the extent |
30 | * map has page->private set to one. | 39 | * map has page->private set to one. |
@@ -288,10 +297,5 @@ int extent_range_uptodate(struct extent_io_tree *tree, | |||
288 | int extent_clear_unlock_delalloc(struct inode *inode, | 297 | int extent_clear_unlock_delalloc(struct inode *inode, |
289 | struct extent_io_tree *tree, | 298 | struct extent_io_tree *tree, |
290 | u64 start, u64 end, struct page *locked_page, | 299 | u64 start, u64 end, struct page *locked_page, |
291 | int unlock_page, | 300 | unsigned long op); |
292 | int clear_unlock, | ||
293 | int clear_delalloc, int clear_dirty, | ||
294 | int set_writeback, | ||
295 | int end_writeback, | ||
296 | int set_private2); | ||
297 | #endif | 301 | #endif |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3a6f953337b5..a7058fca3aab 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -424,9 +424,10 @@ again: | |||
424 | * and free up our temp pages. | 424 | * and free up our temp pages. |
425 | */ | 425 | */ |
426 | extent_clear_unlock_delalloc(inode, | 426 | extent_clear_unlock_delalloc(inode, |
427 | &BTRFS_I(inode)->io_tree, | 427 | &BTRFS_I(inode)->io_tree, |
428 | start, end, NULL, 1, 0, | 428 | start, end, NULL, |
429 | 0, 1, 1, 1, 0); | 429 | EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY | |
430 | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK); | ||
430 | ret = 0; | 431 | ret = 0; |
431 | goto free_pages_out; | 432 | goto free_pages_out; |
432 | } | 433 | } |
@@ -637,11 +638,13 @@ static noinline int submit_compressed_extents(struct inode *inode, | |||
637 | * clear dirty, set writeback and unlock the pages. | 638 | * clear dirty, set writeback and unlock the pages. |
638 | */ | 639 | */ |
639 | extent_clear_unlock_delalloc(inode, | 640 | extent_clear_unlock_delalloc(inode, |
640 | &BTRFS_I(inode)->io_tree, | 641 | &BTRFS_I(inode)->io_tree, |
641 | async_extent->start, | 642 | async_extent->start, |
642 | async_extent->start + | 643 | async_extent->start + |
643 | async_extent->ram_size - 1, | 644 | async_extent->ram_size - 1, |
644 | NULL, 1, 1, 0, 1, 1, 0, 0); | 645 | NULL, EXTENT_CLEAR_UNLOCK_PAGE | |
646 | EXTENT_CLEAR_UNLOCK | | ||
647 | EXTENT_CLEAR_DIRTY | EXTENT_SET_WRITEBACK); | ||
645 | 648 | ||
646 | ret = btrfs_submit_compressed_write(inode, | 649 | ret = btrfs_submit_compressed_write(inode, |
647 | async_extent->start, | 650 | async_extent->start, |
@@ -712,9 +715,14 @@ static noinline int cow_file_range(struct inode *inode, | |||
712 | start, end, 0, NULL); | 715 | start, end, 0, NULL); |
713 | if (ret == 0) { | 716 | if (ret == 0) { |
714 | extent_clear_unlock_delalloc(inode, | 717 | extent_clear_unlock_delalloc(inode, |
715 | &BTRFS_I(inode)->io_tree, | 718 | &BTRFS_I(inode)->io_tree, |
716 | start, end, NULL, 1, 1, | 719 | start, end, NULL, |
717 | 1, 1, 1, 1, 0); | 720 | EXTENT_CLEAR_UNLOCK_PAGE | |
721 | EXTENT_CLEAR_UNLOCK | | ||
722 | EXTENT_CLEAR_DELALLOC | | ||
723 | EXTENT_CLEAR_DIRTY | | ||
724 | EXTENT_SET_WRITEBACK | | ||
725 | EXTENT_END_WRITEBACK); | ||
718 | *nr_written = *nr_written + | 726 | *nr_written = *nr_written + |
719 | (end - start + PAGE_CACHE_SIZE) / PAGE_CACHE_SIZE; | 727 | (end - start + PAGE_CACHE_SIZE) / PAGE_CACHE_SIZE; |
720 | *page_started = 1; | 728 | *page_started = 1; |
@@ -738,6 +746,8 @@ static noinline int cow_file_range(struct inode *inode, | |||
738 | btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0); | 746 | btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0); |
739 | 747 | ||
740 | while (disk_num_bytes > 0) { | 748 | while (disk_num_bytes > 0) { |
749 | unsigned long op; | ||
750 | |||
741 | cur_alloc_size = min(disk_num_bytes, root->fs_info->max_extent); | 751 | cur_alloc_size = min(disk_num_bytes, root->fs_info->max_extent); |
742 | ret = btrfs_reserve_extent(trans, root, cur_alloc_size, | 752 | ret = btrfs_reserve_extent(trans, root, cur_alloc_size, |
743 | root->sectorsize, 0, alloc_hint, | 753 | root->sectorsize, 0, alloc_hint, |
@@ -789,10 +799,13 @@ static noinline int cow_file_range(struct inode *inode, | |||
789 | * Do set the Private2 bit so we know this page was properly | 799 | * Do set the Private2 bit so we know this page was properly |
790 | * setup for writepage | 800 | * setup for writepage |
791 | */ | 801 | */ |
802 | op = unlock ? EXTENT_CLEAR_UNLOCK_PAGE : 0; | ||
803 | op |= EXTENT_CLEAR_UNLOCK | EXTENT_CLEAR_DELALLOC | | ||
804 | EXTENT_SET_PRIVATE2; | ||
805 | |||
792 | extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, | 806 | extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, |
793 | start, start + ram_size - 1, | 807 | start, start + ram_size - 1, |
794 | locked_page, unlock, 1, | 808 | locked_page, op); |
795 | 1, 0, 0, 0, 1); | ||
796 | disk_num_bytes -= cur_alloc_size; | 809 | disk_num_bytes -= cur_alloc_size; |
797 | num_bytes -= cur_alloc_size; | 810 | num_bytes -= cur_alloc_size; |
798 | alloc_hint = ins.objectid + ins.offset; | 811 | alloc_hint = ins.objectid + ins.offset; |
@@ -1112,8 +1125,10 @@ out_check: | |||
1112 | BUG_ON(ret); | 1125 | BUG_ON(ret); |
1113 | 1126 | ||
1114 | extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, | 1127 | extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, |
1115 | cur_offset, cur_offset + num_bytes - 1, | 1128 | cur_offset, cur_offset + num_bytes - 1, |
1116 | locked_page, 1, 1, 1, 0, 0, 0, 1); | 1129 | locked_page, EXTENT_CLEAR_UNLOCK_PAGE | |
1130 | EXTENT_CLEAR_UNLOCK | EXTENT_CLEAR_DELALLOC | | ||
1131 | EXTENT_SET_PRIVATE2); | ||
1117 | cur_offset = extent_end; | 1132 | cur_offset = extent_end; |
1118 | if (cur_offset > end) | 1133 | if (cur_offset > end) |
1119 | break; | 1134 | break; |