summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/extent_io.h5
-rw-r--r--fs/btrfs/file.c43
-rw-r--r--fs/btrfs/inode.c9
-rw-r--r--fs/btrfs/relocation.c3
-rw-r--r--fs/btrfs/tests/extent-io-tests.c6
-rw-r--r--fs/btrfs/tests/inode-tests.c12
7 files changed, 46 insertions, 33 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index f7df5536ab61..72dcbf19f6ce 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3180,6 +3180,7 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput);
3180int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput, 3180int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput,
3181 int nr); 3181 int nr);
3182int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, 3182int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
3183 unsigned int extra_bits,
3183 struct extent_state **cached_state, int dedupe); 3184 struct extent_state **cached_state, int dedupe);
3184int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, 3185int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
3185 struct btrfs_root *new_root, 3186 struct btrfs_root *new_root,
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index d8b27af7101e..2ef824b58e3c 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -365,10 +365,11 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
365 struct extent_state **cached_state); 365 struct extent_state **cached_state);
366 366
367static inline int set_extent_delalloc(struct extent_io_tree *tree, u64 start, 367static inline int set_extent_delalloc(struct extent_io_tree *tree, u64 start,
368 u64 end, struct extent_state **cached_state) 368 u64 end, unsigned int extra_bits,
369 struct extent_state **cached_state)
369{ 370{
370 return set_extent_bit(tree, start, end, 371 return set_extent_bit(tree, start, end,
371 EXTENT_DELALLOC | EXTENT_UPTODATE, 372 EXTENT_DELALLOC | EXTENT_UPTODATE | extra_bits,
372 NULL, cached_state, GFP_NOFS); 373 NULL, cached_state, GFP_NOFS);
373} 374}
374 375
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 47e6ebad78c3..2de7b4f4ca3c 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -538,14 +538,34 @@ int btrfs_dirty_pages(struct inode *inode, struct page **pages,
538 u64 end_of_last_block; 538 u64 end_of_last_block;
539 u64 end_pos = pos + write_bytes; 539 u64 end_pos = pos + write_bytes;
540 loff_t isize = i_size_read(inode); 540 loff_t isize = i_size_read(inode);
541 unsigned int extra_bits = 0;
541 542
542 start_pos = pos & ~((u64) fs_info->sectorsize - 1); 543 start_pos = pos & ~((u64) fs_info->sectorsize - 1);
543 num_bytes = round_up(write_bytes + pos - start_pos, 544 num_bytes = round_up(write_bytes + pos - start_pos,
544 fs_info->sectorsize); 545 fs_info->sectorsize);
545 546
546 end_of_last_block = start_pos + num_bytes - 1; 547 end_of_last_block = start_pos + num_bytes - 1;
548
549 if (!btrfs_is_free_space_inode(BTRFS_I(inode))) {
550 if (start_pos >= isize &&
551 !(BTRFS_I(inode)->flags & BTRFS_INODE_PREALLOC)) {
552 /*
553 * There can't be any extents following eof in this case
554 * so just set the delalloc new bit for the range
555 * directly.
556 */
557 extra_bits |= EXTENT_DELALLOC_NEW;
558 } else {
559 err = btrfs_find_new_delalloc_bytes(BTRFS_I(inode),
560 start_pos,
561 num_bytes, cached);
562 if (err)
563 return err;
564 }
565 }
566
547 err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, 567 err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block,
548 cached, 0); 568 extra_bits, cached, 0);
549 if (err) 569 if (err)
550 return err; 570 return err;
551 571
@@ -1473,10 +1493,8 @@ lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages,
1473 + round_up(pos + write_bytes - start_pos, 1493 + round_up(pos + write_bytes - start_pos,
1474 fs_info->sectorsize) - 1; 1494 fs_info->sectorsize) - 1;
1475 1495
1476 if (start_pos < inode->vfs_inode.i_size || 1496 if (start_pos < inode->vfs_inode.i_size) {
1477 (inode->flags & BTRFS_INODE_PREALLOC)) {
1478 struct btrfs_ordered_extent *ordered; 1497 struct btrfs_ordered_extent *ordered;
1479 unsigned int clear_bits;
1480 1498
1481 lock_extent_bits(&inode->io_tree, start_pos, last_pos, 1499 lock_extent_bits(&inode->io_tree, start_pos, last_pos,
1482 cached_state); 1500 cached_state);
@@ -1498,19 +1516,10 @@ lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages,
1498 } 1516 }
1499 if (ordered) 1517 if (ordered)
1500 btrfs_put_ordered_extent(ordered); 1518 btrfs_put_ordered_extent(ordered);
1501 ret = btrfs_find_new_delalloc_bytes(inode, start_pos, 1519 clear_extent_bit(&inode->io_tree, start_pos, last_pos,
1502 last_pos - start_pos + 1, 1520 EXTENT_DIRTY | EXTENT_DELALLOC |
1503 cached_state); 1521 EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
1504 clear_bits = EXTENT_DIRTY | EXTENT_DELALLOC | 1522 0, 0, cached_state, GFP_NOFS);
1505 EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG;
1506 if (ret)
1507 clear_bits |= EXTENT_DELALLOC_NEW | EXTENT_LOCKED;
1508 clear_extent_bit(&inode->io_tree, start_pos,
1509 last_pos, clear_bits,
1510 (clear_bits & EXTENT_LOCKED) ? 1 : 0,
1511 0, cached_state, GFP_NOFS);
1512 if (ret)
1513 return ret;
1514 *lockstart = start_pos; 1523 *lockstart = start_pos;
1515 *lockend = last_pos; 1524 *lockend = last_pos;
1516 ret = 1; 1525 ret = 1;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1131db7a0b28..993061f83067 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2032,11 +2032,12 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,
2032} 2032}
2033 2033
2034int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, 2034int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
2035 unsigned int extra_bits,
2035 struct extent_state **cached_state, int dedupe) 2036 struct extent_state **cached_state, int dedupe)
2036{ 2037{
2037 WARN_ON((end & (PAGE_SIZE - 1)) == 0); 2038 WARN_ON((end & (PAGE_SIZE - 1)) == 0);
2038 return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end, 2039 return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end,
2039 cached_state); 2040 extra_bits, cached_state);
2040} 2041}
2041 2042
2042/* see btrfs_writepage_start_hook for details on why this is required */ 2043/* see btrfs_writepage_start_hook for details on why this is required */
@@ -2097,7 +2098,7 @@ again:
2097 goto out; 2098 goto out;
2098 } 2099 }
2099 2100
2100 btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state, 2101 btrfs_set_extent_delalloc(inode, page_start, page_end, 0, &cached_state,
2101 0); 2102 0);
2102 ClearPageChecked(page); 2103 ClearPageChecked(page);
2103 set_page_dirty(page); 2104 set_page_dirty(page);
@@ -4797,7 +4798,7 @@ again:
4797 EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 4798 EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
4798 0, 0, &cached_state, GFP_NOFS); 4799 0, 0, &cached_state, GFP_NOFS);
4799 4800
4800 ret = btrfs_set_extent_delalloc(inode, block_start, block_end, 4801 ret = btrfs_set_extent_delalloc(inode, block_start, block_end, 0,
4801 &cached_state, 0); 4802 &cached_state, 0);
4802 if (ret) { 4803 if (ret) {
4803 unlock_extent_cached(io_tree, block_start, block_end, 4804 unlock_extent_cached(io_tree, block_start, block_end,
@@ -9163,7 +9164,7 @@ again:
9163 EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 9164 EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
9164 0, 0, &cached_state, GFP_NOFS); 9165 0, 0, &cached_state, GFP_NOFS);
9165 9166
9166 ret = btrfs_set_extent_delalloc(inode, page_start, end, 9167 ret = btrfs_set_extent_delalloc(inode, page_start, end, 0,
9167 &cached_state, 0); 9168 &cached_state, 0);
9168 if (ret) { 9169 if (ret) {
9169 unlock_extent_cached(io_tree, page_start, page_end, 9170 unlock_extent_cached(io_tree, page_start, page_end,
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 4cf2eb67eba6..f0c3f00e97cb 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3268,7 +3268,8 @@ static int relocate_file_extent_cluster(struct inode *inode,
3268 nr++; 3268 nr++;
3269 } 3269 }
3270 3270
3271 btrfs_set_extent_delalloc(inode, page_start, page_end, NULL, 0); 3271 btrfs_set_extent_delalloc(inode, page_start, page_end, 0, NULL,
3272 0);
3272 set_page_dirty(page); 3273 set_page_dirty(page);
3273 3274
3274 unlock_extent(&BTRFS_I(inode)->io_tree, 3275 unlock_extent(&BTRFS_I(inode)->io_tree,
diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c
index d06b1c931d05..2e7f64a3b22b 100644
--- a/fs/btrfs/tests/extent-io-tests.c
+++ b/fs/btrfs/tests/extent-io-tests.c
@@ -114,7 +114,7 @@ static int test_find_delalloc(u32 sectorsize)
114 * |--- delalloc ---| 114 * |--- delalloc ---|
115 * |--- search ---| 115 * |--- search ---|
116 */ 116 */
117 set_extent_delalloc(&tmp, 0, sectorsize - 1, NULL); 117 set_extent_delalloc(&tmp, 0, sectorsize - 1, 0, NULL);
118 start = 0; 118 start = 0;
119 end = 0; 119 end = 0;
120 found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, 120 found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
@@ -145,7 +145,7 @@ static int test_find_delalloc(u32 sectorsize)
145 test_msg("Couldn't find the locked page\n"); 145 test_msg("Couldn't find the locked page\n");
146 goto out_bits; 146 goto out_bits;
147 } 147 }
148 set_extent_delalloc(&tmp, sectorsize, max_bytes - 1, NULL); 148 set_extent_delalloc(&tmp, sectorsize, max_bytes - 1, 0, NULL);
149 start = test_start; 149 start = test_start;
150 end = 0; 150 end = 0;
151 found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, 151 found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
@@ -200,7 +200,7 @@ static int test_find_delalloc(u32 sectorsize)
200 * 200 *
201 * We are re-using our test_start from above since it works out well. 201 * We are re-using our test_start from above since it works out well.
202 */ 202 */
203 set_extent_delalloc(&tmp, max_bytes, total_dirty - 1, NULL); 203 set_extent_delalloc(&tmp, max_bytes, total_dirty - 1, 0, NULL);
204 start = test_start; 204 start = test_start;
205 end = 0; 205 end = 0;
206 found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, 206 found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
diff --git a/fs/btrfs/tests/inode-tests.c b/fs/btrfs/tests/inode-tests.c
index f797642c013d..30affb60da51 100644
--- a/fs/btrfs/tests/inode-tests.c
+++ b/fs/btrfs/tests/inode-tests.c
@@ -968,7 +968,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
968 btrfs_test_inode_set_ops(inode); 968 btrfs_test_inode_set_ops(inode);
969 969
970 /* [BTRFS_MAX_EXTENT_SIZE] */ 970 /* [BTRFS_MAX_EXTENT_SIZE] */
971 ret = btrfs_set_extent_delalloc(inode, 0, BTRFS_MAX_EXTENT_SIZE - 1, 971 ret = btrfs_set_extent_delalloc(inode, 0, BTRFS_MAX_EXTENT_SIZE - 1, 0,
972 NULL, 0); 972 NULL, 0);
973 if (ret) { 973 if (ret) {
974 test_msg("btrfs_set_extent_delalloc returned %d\n", ret); 974 test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
@@ -984,7 +984,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
984 /* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */ 984 /* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */
985 ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE, 985 ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE,
986 BTRFS_MAX_EXTENT_SIZE + sectorsize - 1, 986 BTRFS_MAX_EXTENT_SIZE + sectorsize - 1,
987 NULL, 0); 987 0, NULL, 0);
988 if (ret) { 988 if (ret) {
989 test_msg("btrfs_set_extent_delalloc returned %d\n", ret); 989 test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
990 goto out; 990 goto out;
@@ -1018,7 +1018,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
1018 ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE >> 1, 1018 ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE >> 1,
1019 (BTRFS_MAX_EXTENT_SIZE >> 1) 1019 (BTRFS_MAX_EXTENT_SIZE >> 1)
1020 + sectorsize - 1, 1020 + sectorsize - 1,
1021 NULL, 0); 1021 0, NULL, 0);
1022 if (ret) { 1022 if (ret) {
1023 test_msg("btrfs_set_extent_delalloc returned %d\n", ret); 1023 test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
1024 goto out; 1024 goto out;
@@ -1036,7 +1036,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
1036 ret = btrfs_set_extent_delalloc(inode, 1036 ret = btrfs_set_extent_delalloc(inode,
1037 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize, 1037 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize,
1038 (BTRFS_MAX_EXTENT_SIZE << 1) + 3 * sectorsize - 1, 1038 (BTRFS_MAX_EXTENT_SIZE << 1) + 3 * sectorsize - 1,
1039 NULL, 0); 1039 0, NULL, 0);
1040 if (ret) { 1040 if (ret) {
1041 test_msg("btrfs_set_extent_delalloc returned %d\n", ret); 1041 test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
1042 goto out; 1042 goto out;
@@ -1053,7 +1053,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
1053 */ 1053 */
1054 ret = btrfs_set_extent_delalloc(inode, 1054 ret = btrfs_set_extent_delalloc(inode,
1055 BTRFS_MAX_EXTENT_SIZE + sectorsize, 1055 BTRFS_MAX_EXTENT_SIZE + sectorsize,
1056 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL, 0); 1056 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 0, NULL, 0);
1057 if (ret) { 1057 if (ret) {
1058 test_msg("btrfs_set_extent_delalloc returned %d\n", ret); 1058 test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
1059 goto out; 1059 goto out;
@@ -1089,7 +1089,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize)
1089 */ 1089 */
1090 ret = btrfs_set_extent_delalloc(inode, 1090 ret = btrfs_set_extent_delalloc(inode,
1091 BTRFS_MAX_EXTENT_SIZE + sectorsize, 1091 BTRFS_MAX_EXTENT_SIZE + sectorsize,
1092 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL, 0); 1092 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 0, NULL, 0);
1093 if (ret) { 1093 if (ret) {
1094 test_msg("btrfs_set_extent_delalloc returned %d\n", ret); 1094 test_msg("btrfs_set_extent_delalloc returned %d\n", ret);
1095 goto out; 1095 goto out;