diff options
-rw-r--r-- | fs/btrfs/extent_io.c | 29 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 9 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 47 | ||||
-rw-r--r-- | fs/btrfs/ordered-data.c | 29 | ||||
-rw-r--r-- | fs/btrfs/ordered-data.h | 3 |
5 files changed, 62 insertions, 55 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index c9a438d374b6..a102422cd92e 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -885,13 +885,6 @@ int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, | |||
885 | NULL, mask); | 885 | NULL, mask); |
886 | } | 886 | } |
887 | 887 | ||
888 | int set_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end, | ||
889 | gfp_t mask) | ||
890 | { | ||
891 | return set_extent_bit(tree, start, end, EXTENT_ORDERED, 0, NULL, NULL, | ||
892 | mask); | ||
893 | } | ||
894 | |||
895 | int set_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, | 888 | int set_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, |
896 | int bits, gfp_t mask) | 889 | int bits, gfp_t mask) |
897 | { | 890 | { |
@@ -921,13 +914,6 @@ int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, | |||
921 | NULL, mask); | 914 | NULL, mask); |
922 | } | 915 | } |
923 | 916 | ||
924 | int clear_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end, | ||
925 | gfp_t mask) | ||
926 | { | ||
927 | return clear_extent_bit(tree, start, end, EXTENT_ORDERED, 1, 0, | ||
928 | NULL, mask); | ||
929 | } | ||
930 | |||
931 | int set_extent_new(struct extent_io_tree *tree, u64 start, u64 end, | 917 | int set_extent_new(struct extent_io_tree *tree, u64 start, u64 end, |
932 | gfp_t mask) | 918 | gfp_t mask) |
933 | { | 919 | { |
@@ -1373,7 +1359,8 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
1373 | int clear_unlock, | 1359 | int clear_unlock, |
1374 | int clear_delalloc, int clear_dirty, | 1360 | int clear_delalloc, int clear_dirty, |
1375 | int set_writeback, | 1361 | int set_writeback, |
1376 | int end_writeback) | 1362 | int end_writeback, |
1363 | int set_private2) | ||
1377 | { | 1364 | { |
1378 | int ret; | 1365 | int ret; |
1379 | struct page *pages[16]; | 1366 | struct page *pages[16]; |
@@ -1392,7 +1379,8 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
1392 | clear_bits |= EXTENT_DELALLOC; | 1379 | clear_bits |= EXTENT_DELALLOC; |
1393 | 1380 | ||
1394 | clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS); | 1381 | clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS); |
1395 | if (!(unlock_pages || clear_dirty || set_writeback || end_writeback)) | 1382 | if (!(unlock_pages || clear_dirty || set_writeback || end_writeback || |
1383 | set_private2)) | ||
1396 | return 0; | 1384 | return 0; |
1397 | 1385 | ||
1398 | while (nr_pages > 0) { | 1386 | while (nr_pages > 0) { |
@@ -1400,6 +1388,10 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
1400 | min_t(unsigned long, | 1388 | min_t(unsigned long, |
1401 | nr_pages, ARRAY_SIZE(pages)), pages); | 1389 | nr_pages, ARRAY_SIZE(pages)), pages); |
1402 | for (i = 0; i < ret; i++) { | 1390 | for (i = 0; i < ret; i++) { |
1391 | |||
1392 | if (set_private2) | ||
1393 | SetPagePrivate2(pages[i]); | ||
1394 | |||
1403 | if (pages[i] == locked_page) { | 1395 | if (pages[i] == locked_page) { |
1404 | page_cache_release(pages[i]); | 1396 | page_cache_release(pages[i]); |
1405 | continue; | 1397 | continue; |
@@ -2792,7 +2784,7 @@ int try_release_extent_state(struct extent_map_tree *map, | |||
2792 | int ret = 1; | 2784 | int ret = 1; |
2793 | 2785 | ||
2794 | if (test_range_bit(tree, start, end, | 2786 | if (test_range_bit(tree, start, end, |
2795 | EXTENT_IOBITS | EXTENT_ORDERED, 0, NULL)) | 2787 | EXTENT_IOBITS, 0, NULL)) |
2796 | ret = 0; | 2788 | ret = 0; |
2797 | else { | 2789 | else { |
2798 | if ((mask & GFP_NOFS) == GFP_NOFS) | 2790 | if ((mask & GFP_NOFS) == GFP_NOFS) |
@@ -2835,8 +2827,7 @@ int try_release_extent_mapping(struct extent_map_tree *map, | |||
2835 | } | 2827 | } |
2836 | if (!test_range_bit(tree, em->start, | 2828 | if (!test_range_bit(tree, em->start, |
2837 | extent_map_end(em) - 1, | 2829 | extent_map_end(em) - 1, |
2838 | EXTENT_LOCKED | EXTENT_WRITEBACK | | 2830 | EXTENT_LOCKED | EXTENT_WRITEBACK, |
2839 | EXTENT_ORDERED, | ||
2840 | 0, NULL)) { | 2831 | 0, NULL)) { |
2841 | remove_extent_mapping(map, em); | 2832 | remove_extent_mapping(map, em); |
2842 | /* once for the rb tree */ | 2833 | /* once for the rb tree */ |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 09cd6fa3cc86..14ed16fd862d 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -13,10 +13,8 @@ | |||
13 | #define EXTENT_DEFRAG (1 << 6) | 13 | #define EXTENT_DEFRAG (1 << 6) |
14 | #define EXTENT_DEFRAG_DONE (1 << 7) | 14 | #define EXTENT_DEFRAG_DONE (1 << 7) |
15 | #define EXTENT_BUFFER_FILLED (1 << 8) | 15 | #define EXTENT_BUFFER_FILLED (1 << 8) |
16 | #define EXTENT_ORDERED (1 << 9) | 16 | #define EXTENT_BOUNDARY (1 << 9) |
17 | #define EXTENT_ORDERED_METADATA (1 << 10) | 17 | #define EXTENT_NODATASUM (1 << 10) |
18 | #define EXTENT_BOUNDARY (1 << 11) | ||
19 | #define EXTENT_NODATASUM (1 << 12) | ||
20 | #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) | 18 | #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) |
21 | 19 | ||
22 | /* flags for bio submission */ | 20 | /* flags for bio submission */ |
@@ -285,5 +283,6 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
285 | int clear_unlock, | 283 | int clear_unlock, |
286 | int clear_delalloc, int clear_dirty, | 284 | int clear_delalloc, int clear_dirty, |
287 | int set_writeback, | 285 | int set_writeback, |
288 | int end_writeback); | 286 | int end_writeback, |
287 | int set_private2); | ||
289 | #endif | 288 | #endif |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3f8e93de2989..739a245e25d6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -426,7 +426,7 @@ again: | |||
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, 1, 0, |
429 | 0, 1, 1, 1); | 429 | 0, 1, 1, 1, 0); |
430 | ret = 0; | 430 | ret = 0; |
431 | goto free_pages_out; | 431 | goto free_pages_out; |
432 | } | 432 | } |
@@ -641,7 +641,7 @@ static noinline int submit_compressed_extents(struct inode *inode, | |||
641 | async_extent->start, | 641 | async_extent->start, |
642 | async_extent->start + | 642 | async_extent->start + |
643 | async_extent->ram_size - 1, | 643 | async_extent->ram_size - 1, |
644 | NULL, 1, 1, 0, 1, 1, 0); | 644 | NULL, 1, 1, 0, 1, 1, 0, 0); |
645 | 645 | ||
646 | ret = btrfs_submit_compressed_write(inode, | 646 | ret = btrfs_submit_compressed_write(inode, |
647 | async_extent->start, | 647 | async_extent->start, |
@@ -714,7 +714,7 @@ static noinline int cow_file_range(struct inode *inode, | |||
714 | extent_clear_unlock_delalloc(inode, | 714 | extent_clear_unlock_delalloc(inode, |
715 | &BTRFS_I(inode)->io_tree, | 715 | &BTRFS_I(inode)->io_tree, |
716 | start, end, NULL, 1, 1, | 716 | start, end, NULL, 1, 1, |
717 | 1, 1, 1, 1); | 717 | 1, 1, 1, 1, 0); |
718 | *nr_written = *nr_written + | 718 | *nr_written = *nr_written + |
719 | (end - start + PAGE_CACHE_SIZE) / PAGE_CACHE_SIZE; | 719 | (end - start + PAGE_CACHE_SIZE) / PAGE_CACHE_SIZE; |
720 | *page_started = 1; | 720 | *page_started = 1; |
@@ -777,11 +777,14 @@ static noinline int cow_file_range(struct inode *inode, | |||
777 | /* we're not doing compressed IO, don't unlock the first | 777 | /* we're not doing compressed IO, don't unlock the first |
778 | * page (which the caller expects to stay locked), don't | 778 | * page (which the caller expects to stay locked), don't |
779 | * clear any dirty bits and don't set any writeback bits | 779 | * clear any dirty bits and don't set any writeback bits |
780 | * | ||
781 | * Do set the Private2 bit so we know this page was properly | ||
782 | * setup for writepage | ||
780 | */ | 783 | */ |
781 | extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, | 784 | extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, |
782 | start, start + ram_size - 1, | 785 | start, start + ram_size - 1, |
783 | locked_page, unlock, 1, | 786 | locked_page, unlock, 1, |
784 | 1, 0, 0, 0); | 787 | 1, 0, 0, 0, 1); |
785 | disk_num_bytes -= cur_alloc_size; | 788 | disk_num_bytes -= cur_alloc_size; |
786 | num_bytes -= cur_alloc_size; | 789 | num_bytes -= cur_alloc_size; |
787 | alloc_hint = ins.objectid + ins.offset; | 790 | alloc_hint = ins.objectid + ins.offset; |
@@ -1102,7 +1105,7 @@ out_check: | |||
1102 | 1105 | ||
1103 | extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, | 1106 | extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, |
1104 | cur_offset, cur_offset + num_bytes - 1, | 1107 | cur_offset, cur_offset + num_bytes - 1, |
1105 | locked_page, 1, 1, 1, 0, 0, 0); | 1108 | locked_page, 1, 1, 1, 0, 0, 0, 1); |
1106 | cur_offset = extent_end; | 1109 | cur_offset = extent_end; |
1107 | if (cur_offset > end) | 1110 | if (cur_offset > end) |
1108 | break; | 1111 | break; |
@@ -1375,10 +1378,8 @@ again: | |||
1375 | lock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS); | 1378 | lock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS); |
1376 | 1379 | ||
1377 | /* already ordered? We're done */ | 1380 | /* already ordered? We're done */ |
1378 | if (test_range_bit(&BTRFS_I(inode)->io_tree, page_start, page_end, | 1381 | if (PagePrivate2(page)) |
1379 | EXTENT_ORDERED, 0, NULL)) { | ||
1380 | goto out; | 1382 | goto out; |
1381 | } | ||
1382 | 1383 | ||
1383 | ordered = btrfs_lookup_ordered_extent(inode, page_start); | 1384 | ordered = btrfs_lookup_ordered_extent(inode, page_start); |
1384 | if (ordered) { | 1385 | if (ordered) { |
@@ -1414,11 +1415,9 @@ static int btrfs_writepage_start_hook(struct page *page, u64 start, u64 end) | |||
1414 | struct inode *inode = page->mapping->host; | 1415 | struct inode *inode = page->mapping->host; |
1415 | struct btrfs_writepage_fixup *fixup; | 1416 | struct btrfs_writepage_fixup *fixup; |
1416 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1417 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1417 | int ret; | ||
1418 | 1418 | ||
1419 | ret = test_range_bit(&BTRFS_I(inode)->io_tree, start, end, | 1419 | /* this page is properly in the ordered list */ |
1420 | EXTENT_ORDERED, 0, NULL); | 1420 | if (TestClearPagePrivate2(page)) |
1421 | if (ret) | ||
1422 | return 0; | 1421 | return 0; |
1423 | 1422 | ||
1424 | if (PageChecked(page)) | 1423 | if (PageChecked(page)) |
@@ -1624,6 +1623,7 @@ nocow: | |||
1624 | static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end, | 1623 | static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end, |
1625 | struct extent_state *state, int uptodate) | 1624 | struct extent_state *state, int uptodate) |
1626 | { | 1625 | { |
1626 | ClearPagePrivate2(page); | ||
1627 | return btrfs_finish_ordered_io(page->mapping->host, start, end); | 1627 | return btrfs_finish_ordered_io(page->mapping->host, start, end); |
1628 | } | 1628 | } |
1629 | 1629 | ||
@@ -4403,13 +4403,21 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) | |||
4403 | u64 page_start = page_offset(page); | 4403 | u64 page_start = page_offset(page); |
4404 | u64 page_end = page_start + PAGE_CACHE_SIZE - 1; | 4404 | u64 page_end = page_start + PAGE_CACHE_SIZE - 1; |
4405 | 4405 | ||
4406 | |||
4407 | /* | ||
4408 | * we have the page locked, so new writeback can't start, | ||
4409 | * and the dirty bit won't be cleared while we are here. | ||
4410 | * | ||
4411 | * Wait for IO on this page so that we can safely clear | ||
4412 | * the PagePrivate2 bit and do ordered accounting | ||
4413 | */ | ||
4406 | wait_on_page_writeback(page); | 4414 | wait_on_page_writeback(page); |
4415 | |||
4407 | tree = &BTRFS_I(page->mapping->host)->io_tree; | 4416 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
4408 | if (offset) { | 4417 | if (offset) { |
4409 | btrfs_releasepage(page, GFP_NOFS); | 4418 | btrfs_releasepage(page, GFP_NOFS); |
4410 | return; | 4419 | return; |
4411 | } | 4420 | } |
4412 | |||
4413 | lock_extent(tree, page_start, page_end, GFP_NOFS); | 4421 | lock_extent(tree, page_start, page_end, GFP_NOFS); |
4414 | ordered = btrfs_lookup_ordered_extent(page->mapping->host, | 4422 | ordered = btrfs_lookup_ordered_extent(page->mapping->host, |
4415 | page_offset(page)); | 4423 | page_offset(page)); |
@@ -4421,14 +4429,19 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) | |||
4421 | clear_extent_bit(tree, page_start, page_end, | 4429 | clear_extent_bit(tree, page_start, page_end, |
4422 | EXTENT_DIRTY | EXTENT_DELALLOC | | 4430 | EXTENT_DIRTY | EXTENT_DELALLOC | |
4423 | EXTENT_LOCKED, 1, 0, NULL, GFP_NOFS); | 4431 | EXTENT_LOCKED, 1, 0, NULL, GFP_NOFS); |
4424 | btrfs_finish_ordered_io(page->mapping->host, | 4432 | /* |
4425 | page_start, page_end); | 4433 | * whoever cleared the private bit is responsible |
4434 | * for the finish_ordered_io | ||
4435 | */ | ||
4436 | if (TestClearPagePrivate2(page)) { | ||
4437 | btrfs_finish_ordered_io(page->mapping->host, | ||
4438 | page_start, page_end); | ||
4439 | } | ||
4426 | btrfs_put_ordered_extent(ordered); | 4440 | btrfs_put_ordered_extent(ordered); |
4427 | lock_extent(tree, page_start, page_end, GFP_NOFS); | 4441 | lock_extent(tree, page_start, page_end, GFP_NOFS); |
4428 | } | 4442 | } |
4429 | clear_extent_bit(tree, page_start, page_end, | 4443 | clear_extent_bit(tree, page_start, page_end, |
4430 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | | 4444 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC, |
4431 | EXTENT_ORDERED, | ||
4432 | 1, 1, NULL, GFP_NOFS); | 4445 | 1, 1, NULL, GFP_NOFS); |
4433 | __btrfs_releasepage(page, GFP_NOFS); | 4446 | __btrfs_releasepage(page, GFP_NOFS); |
4434 | 4447 | ||
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 7f751e462f0b..4a9c8c4cec25 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -159,8 +159,6 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree, | |||
159 | * | 159 | * |
160 | * len is the length of the extent | 160 | * len is the length of the extent |
161 | * | 161 | * |
162 | * This also sets the EXTENT_ORDERED bit on the range in the inode. | ||
163 | * | ||
164 | * The tree is given a single reference on the ordered extent that was | 162 | * The tree is given a single reference on the ordered extent that was |
165 | * inserted. | 163 | * inserted. |
166 | */ | 164 | */ |
@@ -181,6 +179,7 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | |||
181 | entry->start = start; | 179 | entry->start = start; |
182 | entry->len = len; | 180 | entry->len = len; |
183 | entry->disk_len = disk_len; | 181 | entry->disk_len = disk_len; |
182 | entry->bytes_left = len; | ||
184 | entry->inode = inode; | 183 | entry->inode = inode; |
185 | if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE) | 184 | if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE) |
186 | set_bit(type, &entry->flags); | 185 | set_bit(type, &entry->flags); |
@@ -195,9 +194,6 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | |||
195 | &entry->rb_node); | 194 | &entry->rb_node); |
196 | BUG_ON(node); | 195 | BUG_ON(node); |
197 | 196 | ||
198 | set_extent_ordered(&BTRFS_I(inode)->io_tree, file_offset, | ||
199 | entry_end(entry) - 1, GFP_NOFS); | ||
200 | |||
201 | spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 197 | spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); |
202 | list_add_tail(&entry->root_extent_list, | 198 | list_add_tail(&entry->root_extent_list, |
203 | &BTRFS_I(inode)->root->fs_info->ordered_extents); | 199 | &BTRFS_I(inode)->root->fs_info->ordered_extents); |
@@ -241,13 +237,10 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, | |||
241 | struct btrfs_ordered_inode_tree *tree; | 237 | struct btrfs_ordered_inode_tree *tree; |
242 | struct rb_node *node; | 238 | struct rb_node *node; |
243 | struct btrfs_ordered_extent *entry; | 239 | struct btrfs_ordered_extent *entry; |
244 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | ||
245 | int ret; | 240 | int ret; |
246 | 241 | ||
247 | tree = &BTRFS_I(inode)->ordered_tree; | 242 | tree = &BTRFS_I(inode)->ordered_tree; |
248 | mutex_lock(&tree->mutex); | 243 | mutex_lock(&tree->mutex); |
249 | clear_extent_ordered(io_tree, file_offset, file_offset + io_size - 1, | ||
250 | GFP_NOFS); | ||
251 | node = tree_search(tree, file_offset); | 244 | node = tree_search(tree, file_offset); |
252 | if (!node) { | 245 | if (!node) { |
253 | ret = 1; | 246 | ret = 1; |
@@ -260,11 +253,16 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, | |||
260 | goto out; | 253 | goto out; |
261 | } | 254 | } |
262 | 255 | ||
263 | ret = test_range_bit(io_tree, entry->file_offset, | 256 | if (io_size > entry->bytes_left) { |
264 | entry->file_offset + entry->len - 1, | 257 | printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n", |
265 | EXTENT_ORDERED, 0, NULL); | 258 | (unsigned long long)entry->bytes_left, |
266 | if (ret == 0) | 259 | (unsigned long long)io_size); |
260 | } | ||
261 | entry->bytes_left -= io_size; | ||
262 | if (entry->bytes_left == 0) | ||
267 | ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags); | 263 | ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags); |
264 | else | ||
265 | ret = 1; | ||
268 | out: | 266 | out: |
269 | mutex_unlock(&tree->mutex); | 267 | mutex_unlock(&tree->mutex); |
270 | return ret == 0; | 268 | return ret == 0; |
@@ -476,6 +474,7 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) | |||
476 | u64 orig_end; | 474 | u64 orig_end; |
477 | u64 wait_end; | 475 | u64 wait_end; |
478 | struct btrfs_ordered_extent *ordered; | 476 | struct btrfs_ordered_extent *ordered; |
477 | int found; | ||
479 | 478 | ||
480 | if (start + len < start) { | 479 | if (start + len < start) { |
481 | orig_end = INT_LIMIT(loff_t); | 480 | orig_end = INT_LIMIT(loff_t); |
@@ -502,6 +501,7 @@ again: | |||
502 | orig_end >> PAGE_CACHE_SHIFT); | 501 | orig_end >> PAGE_CACHE_SHIFT); |
503 | 502 | ||
504 | end = orig_end; | 503 | end = orig_end; |
504 | found = 0; | ||
505 | while (1) { | 505 | while (1) { |
506 | ordered = btrfs_lookup_first_ordered_extent(inode, end); | 506 | ordered = btrfs_lookup_first_ordered_extent(inode, end); |
507 | if (!ordered) | 507 | if (!ordered) |
@@ -514,6 +514,7 @@ again: | |||
514 | btrfs_put_ordered_extent(ordered); | 514 | btrfs_put_ordered_extent(ordered); |
515 | break; | 515 | break; |
516 | } | 516 | } |
517 | found++; | ||
517 | btrfs_start_ordered_extent(inode, ordered, 1); | 518 | btrfs_start_ordered_extent(inode, ordered, 1); |
518 | end = ordered->file_offset; | 519 | end = ordered->file_offset; |
519 | btrfs_put_ordered_extent(ordered); | 520 | btrfs_put_ordered_extent(ordered); |
@@ -521,8 +522,8 @@ again: | |||
521 | break; | 522 | break; |
522 | end--; | 523 | end--; |
523 | } | 524 | } |
524 | if (test_range_bit(&BTRFS_I(inode)->io_tree, start, orig_end, | 525 | if (found || test_range_bit(&BTRFS_I(inode)->io_tree, start, orig_end, |
525 | EXTENT_ORDERED | EXTENT_DELALLOC, 0, NULL)) { | 526 | EXTENT_DELALLOC, 0, NULL)) { |
526 | schedule_timeout(1); | 527 | schedule_timeout(1); |
527 | goto again; | 528 | goto again; |
528 | } | 529 | } |
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index 3d31c8827b01..993a7ea45c70 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h | |||
@@ -85,6 +85,9 @@ struct btrfs_ordered_extent { | |||
85 | /* extent length on disk */ | 85 | /* extent length on disk */ |
86 | u64 disk_len; | 86 | u64 disk_len; |
87 | 87 | ||
88 | /* number of bytes that still need writing */ | ||
89 | u64 bytes_left; | ||
90 | |||
88 | /* flags (described above) */ | 91 | /* flags (described above) */ |
89 | unsigned long flags; | 92 | unsigned long flags; |
90 | 93 | ||