diff options
-rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 5 | ||||
-rw-r--r-- | fs/btrfs/file.c | 43 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 9 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 3 | ||||
-rw-r--r-- | fs/btrfs/tests/extent-io-tests.c | 6 | ||||
-rw-r--r-- | fs/btrfs/tests/inode-tests.c | 12 |
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); | |||
3180 | int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput, | 3180 | int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput, |
3181 | int nr); | 3181 | int nr); |
3182 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, | 3182 | int 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); |
3184 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | 3185 | int 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 | ||
367 | static inline int set_extent_delalloc(struct extent_io_tree *tree, u64 start, | 367 | static 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 | ||
2034 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, | 2034 | int 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; |