diff options
| -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; |
