diff options
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r-- | fs/btrfs/extent_io.c | 85 |
1 files changed, 45 insertions, 40 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index d2d03684fab2..a4080c21ec55 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -135,7 +135,7 @@ static struct extent_state *alloc_extent_state(gfp_t mask) | |||
135 | return state; | 135 | return state; |
136 | } | 136 | } |
137 | 137 | ||
138 | static void free_extent_state(struct extent_state *state) | 138 | void free_extent_state(struct extent_state *state) |
139 | { | 139 | { |
140 | if (!state) | 140 | if (!state) |
141 | return; | 141 | return; |
@@ -335,21 +335,18 @@ static int merge_state(struct extent_io_tree *tree, | |||
335 | } | 335 | } |
336 | 336 | ||
337 | static int set_state_cb(struct extent_io_tree *tree, | 337 | static int set_state_cb(struct extent_io_tree *tree, |
338 | struct extent_state *state, | 338 | struct extent_state *state, int *bits) |
339 | unsigned long bits) | ||
340 | { | 339 | { |
341 | if (tree->ops && tree->ops->set_bit_hook) { | 340 | if (tree->ops && tree->ops->set_bit_hook) { |
342 | return tree->ops->set_bit_hook(tree->mapping->host, | 341 | return tree->ops->set_bit_hook(tree->mapping->host, |
343 | state->start, state->end, | 342 | state, bits); |
344 | state->state, bits); | ||
345 | } | 343 | } |
346 | 344 | ||
347 | return 0; | 345 | return 0; |
348 | } | 346 | } |
349 | 347 | ||
350 | static void clear_state_cb(struct extent_io_tree *tree, | 348 | static void clear_state_cb(struct extent_io_tree *tree, |
351 | struct extent_state *state, | 349 | struct extent_state *state, int *bits) |
352 | unsigned long bits) | ||
353 | { | 350 | { |
354 | if (tree->ops && tree->ops->clear_bit_hook) | 351 | if (tree->ops && tree->ops->clear_bit_hook) |
355 | tree->ops->clear_bit_hook(tree->mapping->host, state, bits); | 352 | tree->ops->clear_bit_hook(tree->mapping->host, state, bits); |
@@ -367,9 +364,10 @@ static void clear_state_cb(struct extent_io_tree *tree, | |||
367 | */ | 364 | */ |
368 | static int insert_state(struct extent_io_tree *tree, | 365 | static int insert_state(struct extent_io_tree *tree, |
369 | struct extent_state *state, u64 start, u64 end, | 366 | struct extent_state *state, u64 start, u64 end, |
370 | int bits) | 367 | int *bits) |
371 | { | 368 | { |
372 | struct rb_node *node; | 369 | struct rb_node *node; |
370 | int bits_to_set = *bits & ~EXTENT_CTLBITS; | ||
373 | int ret; | 371 | int ret; |
374 | 372 | ||
375 | if (end < start) { | 373 | if (end < start) { |
@@ -384,9 +382,9 @@ static int insert_state(struct extent_io_tree *tree, | |||
384 | if (ret) | 382 | if (ret) |
385 | return ret; | 383 | return ret; |
386 | 384 | ||
387 | if (bits & EXTENT_DIRTY) | 385 | if (bits_to_set & EXTENT_DIRTY) |
388 | tree->dirty_bytes += end - start + 1; | 386 | tree->dirty_bytes += end - start + 1; |
389 | state->state |= bits; | 387 | state->state |= bits_to_set; |
390 | node = tree_insert(&tree->state, end, &state->rb_node); | 388 | node = tree_insert(&tree->state, end, &state->rb_node); |
391 | if (node) { | 389 | if (node) { |
392 | struct extent_state *found; | 390 | struct extent_state *found; |
@@ -456,13 +454,13 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig, | |||
456 | * struct is freed and removed from the tree | 454 | * struct is freed and removed from the tree |
457 | */ | 455 | */ |
458 | static int clear_state_bit(struct extent_io_tree *tree, | 456 | static int clear_state_bit(struct extent_io_tree *tree, |
459 | struct extent_state *state, int bits, int wake, | 457 | struct extent_state *state, |
460 | int delete) | 458 | int *bits, int wake) |
461 | { | 459 | { |
462 | int bits_to_clear = bits & ~EXTENT_DO_ACCOUNTING; | 460 | int bits_to_clear = *bits & ~EXTENT_CTLBITS; |
463 | int ret = state->state & bits_to_clear; | 461 | int ret = state->state & bits_to_clear; |
464 | 462 | ||
465 | if ((bits & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) { | 463 | if ((bits_to_clear & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) { |
466 | u64 range = state->end - state->start + 1; | 464 | u64 range = state->end - state->start + 1; |
467 | WARN_ON(range > tree->dirty_bytes); | 465 | WARN_ON(range > tree->dirty_bytes); |
468 | tree->dirty_bytes -= range; | 466 | tree->dirty_bytes -= range; |
@@ -471,9 +469,8 @@ static int clear_state_bit(struct extent_io_tree *tree, | |||
471 | state->state &= ~bits_to_clear; | 469 | state->state &= ~bits_to_clear; |
472 | if (wake) | 470 | if (wake) |
473 | wake_up(&state->wq); | 471 | wake_up(&state->wq); |
474 | if (delete || state->state == 0) { | 472 | if (state->state == 0) { |
475 | if (state->tree) { | 473 | if (state->tree) { |
476 | clear_state_cb(tree, state, state->state); | ||
477 | rb_erase(&state->rb_node, &tree->state); | 474 | rb_erase(&state->rb_node, &tree->state); |
478 | state->tree = NULL; | 475 | state->tree = NULL; |
479 | free_extent_state(state); | 476 | free_extent_state(state); |
@@ -514,6 +511,10 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, | |||
514 | int set = 0; | 511 | int set = 0; |
515 | int clear = 0; | 512 | int clear = 0; |
516 | 513 | ||
514 | if (delete) | ||
515 | bits |= ~EXTENT_CTLBITS; | ||
516 | bits |= EXTENT_FIRST_DELALLOC; | ||
517 | |||
517 | if (bits & (EXTENT_IOBITS | EXTENT_BOUNDARY)) | 518 | if (bits & (EXTENT_IOBITS | EXTENT_BOUNDARY)) |
518 | clear = 1; | 519 | clear = 1; |
519 | again: | 520 | again: |
@@ -580,8 +581,7 @@ hit_next: | |||
580 | if (err) | 581 | if (err) |
581 | goto out; | 582 | goto out; |
582 | if (state->end <= end) { | 583 | if (state->end <= end) { |
583 | set |= clear_state_bit(tree, state, bits, wake, | 584 | set |= clear_state_bit(tree, state, &bits, wake); |
584 | delete); | ||
585 | if (last_end == (u64)-1) | 585 | if (last_end == (u64)-1) |
586 | goto out; | 586 | goto out; |
587 | start = last_end + 1; | 587 | start = last_end + 1; |
@@ -602,7 +602,7 @@ hit_next: | |||
602 | if (wake) | 602 | if (wake) |
603 | wake_up(&state->wq); | 603 | wake_up(&state->wq); |
604 | 604 | ||
605 | set |= clear_state_bit(tree, prealloc, bits, wake, delete); | 605 | set |= clear_state_bit(tree, prealloc, &bits, wake); |
606 | 606 | ||
607 | prealloc = NULL; | 607 | prealloc = NULL; |
608 | goto out; | 608 | goto out; |
@@ -613,7 +613,7 @@ hit_next: | |||
613 | else | 613 | else |
614 | next_node = NULL; | 614 | next_node = NULL; |
615 | 615 | ||
616 | set |= clear_state_bit(tree, state, bits, wake, delete); | 616 | set |= clear_state_bit(tree, state, &bits, wake); |
617 | if (last_end == (u64)-1) | 617 | if (last_end == (u64)-1) |
618 | goto out; | 618 | goto out; |
619 | start = last_end + 1; | 619 | start = last_end + 1; |
@@ -706,19 +706,19 @@ out: | |||
706 | 706 | ||
707 | static int set_state_bits(struct extent_io_tree *tree, | 707 | static int set_state_bits(struct extent_io_tree *tree, |
708 | struct extent_state *state, | 708 | struct extent_state *state, |
709 | int bits) | 709 | int *bits) |
710 | { | 710 | { |
711 | int ret; | 711 | int ret; |
712 | int bits_to_set = *bits & ~EXTENT_CTLBITS; | ||
712 | 713 | ||
713 | ret = set_state_cb(tree, state, bits); | 714 | ret = set_state_cb(tree, state, bits); |
714 | if (ret) | 715 | if (ret) |
715 | return ret; | 716 | return ret; |
716 | 717 | if ((bits_to_set & EXTENT_DIRTY) && !(state->state & EXTENT_DIRTY)) { | |
717 | if ((bits & EXTENT_DIRTY) && !(state->state & EXTENT_DIRTY)) { | ||
718 | u64 range = state->end - state->start + 1; | 718 | u64 range = state->end - state->start + 1; |
719 | tree->dirty_bytes += range; | 719 | tree->dirty_bytes += range; |
720 | } | 720 | } |
721 | state->state |= bits; | 721 | state->state |= bits_to_set; |
722 | 722 | ||
723 | return 0; | 723 | return 0; |
724 | } | 724 | } |
@@ -745,10 +745,9 @@ static void cache_state(struct extent_state *state, | |||
745 | * [start, end] is inclusive This takes the tree lock. | 745 | * [start, end] is inclusive This takes the tree lock. |
746 | */ | 746 | */ |
747 | 747 | ||
748 | static int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, | 748 | int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, |
749 | int bits, int exclusive_bits, u64 *failed_start, | 749 | int bits, int exclusive_bits, u64 *failed_start, |
750 | struct extent_state **cached_state, | 750 | struct extent_state **cached_state, gfp_t mask) |
751 | gfp_t mask) | ||
752 | { | 751 | { |
753 | struct extent_state *state; | 752 | struct extent_state *state; |
754 | struct extent_state *prealloc = NULL; | 753 | struct extent_state *prealloc = NULL; |
@@ -757,6 +756,7 @@ static int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, | |||
757 | u64 last_start; | 756 | u64 last_start; |
758 | u64 last_end; | 757 | u64 last_end; |
759 | 758 | ||
759 | bits |= EXTENT_FIRST_DELALLOC; | ||
760 | again: | 760 | again: |
761 | if (!prealloc && (mask & __GFP_WAIT)) { | 761 | if (!prealloc && (mask & __GFP_WAIT)) { |
762 | prealloc = alloc_extent_state(mask); | 762 | prealloc = alloc_extent_state(mask); |
@@ -778,7 +778,7 @@ again: | |||
778 | */ | 778 | */ |
779 | node = tree_search(tree, start); | 779 | node = tree_search(tree, start); |
780 | if (!node) { | 780 | if (!node) { |
781 | err = insert_state(tree, prealloc, start, end, bits); | 781 | err = insert_state(tree, prealloc, start, end, &bits); |
782 | prealloc = NULL; | 782 | prealloc = NULL; |
783 | BUG_ON(err == -EEXIST); | 783 | BUG_ON(err == -EEXIST); |
784 | goto out; | 784 | goto out; |
@@ -802,7 +802,7 @@ hit_next: | |||
802 | goto out; | 802 | goto out; |
803 | } | 803 | } |
804 | 804 | ||
805 | err = set_state_bits(tree, state, bits); | 805 | err = set_state_bits(tree, state, &bits); |
806 | if (err) | 806 | if (err) |
807 | goto out; | 807 | goto out; |
808 | 808 | ||
@@ -852,7 +852,7 @@ hit_next: | |||
852 | if (err) | 852 | if (err) |
853 | goto out; | 853 | goto out; |
854 | if (state->end <= end) { | 854 | if (state->end <= end) { |
855 | err = set_state_bits(tree, state, bits); | 855 | err = set_state_bits(tree, state, &bits); |
856 | if (err) | 856 | if (err) |
857 | goto out; | 857 | goto out; |
858 | cache_state(state, cached_state); | 858 | cache_state(state, cached_state); |
@@ -877,7 +877,7 @@ hit_next: | |||
877 | else | 877 | else |
878 | this_end = last_start - 1; | 878 | this_end = last_start - 1; |
879 | err = insert_state(tree, prealloc, start, this_end, | 879 | err = insert_state(tree, prealloc, start, this_end, |
880 | bits); | 880 | &bits); |
881 | BUG_ON(err == -EEXIST); | 881 | BUG_ON(err == -EEXIST); |
882 | if (err) { | 882 | if (err) { |
883 | prealloc = NULL; | 883 | prealloc = NULL; |
@@ -903,7 +903,7 @@ hit_next: | |||
903 | err = split_state(tree, state, prealloc, end + 1); | 903 | err = split_state(tree, state, prealloc, end + 1); |
904 | BUG_ON(err == -EEXIST); | 904 | BUG_ON(err == -EEXIST); |
905 | 905 | ||
906 | err = set_state_bits(tree, prealloc, bits); | 906 | err = set_state_bits(tree, prealloc, &bits); |
907 | if (err) { | 907 | if (err) { |
908 | prealloc = NULL; | 908 | prealloc = NULL; |
909 | goto out; | 909 | goto out; |
@@ -966,8 +966,7 @@ int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, | |||
966 | { | 966 | { |
967 | return clear_extent_bit(tree, start, end, | 967 | return clear_extent_bit(tree, start, end, |
968 | EXTENT_DIRTY | EXTENT_DELALLOC | | 968 | EXTENT_DIRTY | EXTENT_DELALLOC | |
969 | EXTENT_DO_ACCOUNTING, 0, 0, | 969 | EXTENT_DO_ACCOUNTING, 0, 0, NULL, mask); |
970 | NULL, mask); | ||
971 | } | 970 | } |
972 | 971 | ||
973 | int set_extent_new(struct extent_io_tree *tree, u64 start, u64 end, | 972 | int set_extent_new(struct extent_io_tree *tree, u64 start, u64 end, |
@@ -1435,9 +1434,6 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
1435 | if (op & EXTENT_CLEAR_DELALLOC) | 1434 | if (op & EXTENT_CLEAR_DELALLOC) |
1436 | clear_bits |= EXTENT_DELALLOC; | 1435 | clear_bits |= EXTENT_DELALLOC; |
1437 | 1436 | ||
1438 | if (op & EXTENT_CLEAR_ACCOUNTING) | ||
1439 | clear_bits |= EXTENT_DO_ACCOUNTING; | ||
1440 | |||
1441 | clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS); | 1437 | clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS); |
1442 | if (!(op & (EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY | | 1438 | if (!(op & (EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY | |
1443 | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK | | 1439 | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK | |
@@ -1916,7 +1912,7 @@ static int submit_one_bio(int rw, struct bio *bio, int mirror_num, | |||
1916 | 1912 | ||
1917 | if (tree->ops && tree->ops->submit_bio_hook) | 1913 | if (tree->ops && tree->ops->submit_bio_hook) |
1918 | tree->ops->submit_bio_hook(page->mapping->host, rw, bio, | 1914 | tree->ops->submit_bio_hook(page->mapping->host, rw, bio, |
1919 | mirror_num, bio_flags); | 1915 | mirror_num, bio_flags, start); |
1920 | else | 1916 | else |
1921 | submit_bio(rw, bio); | 1917 | submit_bio(rw, bio); |
1922 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) | 1918 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) |
@@ -2020,6 +2016,7 @@ static int __extent_read_full_page(struct extent_io_tree *tree, | |||
2020 | sector_t sector; | 2016 | sector_t sector; |
2021 | struct extent_map *em; | 2017 | struct extent_map *em; |
2022 | struct block_device *bdev; | 2018 | struct block_device *bdev; |
2019 | struct btrfs_ordered_extent *ordered; | ||
2023 | int ret; | 2020 | int ret; |
2024 | int nr = 0; | 2021 | int nr = 0; |
2025 | size_t page_offset = 0; | 2022 | size_t page_offset = 0; |
@@ -2031,7 +2028,15 @@ static int __extent_read_full_page(struct extent_io_tree *tree, | |||
2031 | set_page_extent_mapped(page); | 2028 | set_page_extent_mapped(page); |
2032 | 2029 | ||
2033 | end = page_end; | 2030 | end = page_end; |
2034 | lock_extent(tree, start, end, GFP_NOFS); | 2031 | while (1) { |
2032 | lock_extent(tree, start, end, GFP_NOFS); | ||
2033 | ordered = btrfs_lookup_ordered_extent(inode, start); | ||
2034 | if (!ordered) | ||
2035 | break; | ||
2036 | unlock_extent(tree, start, end, GFP_NOFS); | ||
2037 | btrfs_start_ordered_extent(inode, ordered, 1); | ||
2038 | btrfs_put_ordered_extent(ordered); | ||
2039 | } | ||
2035 | 2040 | ||
2036 | if (page->index == last_byte >> PAGE_CACHE_SHIFT) { | 2041 | if (page->index == last_byte >> PAGE_CACHE_SHIFT) { |
2037 | char *userpage; | 2042 | char *userpage; |