aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent_io.c27
-rw-r--r--fs/btrfs/extent_io.h16
-rw-r--r--fs/btrfs/inode.c45
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:
1401int extent_clear_unlock_delalloc(struct inode *inode, 1401int 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,
288int extent_clear_unlock_delalloc(struct inode *inode, 297int 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;