diff options
Diffstat (limited to 'fs/btrfs/extent_io.c')
| -rw-r--r-- | fs/btrfs/extent_io.c | 103 |
1 files changed, 46 insertions, 57 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index c99121ac5d6b..d74e6af9b53a 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | #include <linux/slab.h> | 2 | #include <linux/slab.h> |
| 3 | #include <linux/bio.h> | 3 | #include <linux/bio.h> |
| 4 | #include <linux/mm.h> | 4 | #include <linux/mm.h> |
| 5 | #include <linux/gfp.h> | ||
| 6 | #include <linux/pagemap.h> | 5 | #include <linux/pagemap.h> |
| 7 | #include <linux/page-flags.h> | 6 | #include <linux/page-flags.h> |
| 8 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| @@ -136,7 +135,7 @@ static struct extent_state *alloc_extent_state(gfp_t mask) | |||
| 136 | return state; | 135 | return state; |
| 137 | } | 136 | } |
| 138 | 137 | ||
| 139 | static void free_extent_state(struct extent_state *state) | 138 | void free_extent_state(struct extent_state *state) |
| 140 | { | 139 | { |
| 141 | if (!state) | 140 | if (!state) |
| 142 | return; | 141 | return; |
| @@ -336,21 +335,18 @@ static int merge_state(struct extent_io_tree *tree, | |||
| 336 | } | 335 | } |
| 337 | 336 | ||
| 338 | static int set_state_cb(struct extent_io_tree *tree, | 337 | static int set_state_cb(struct extent_io_tree *tree, |
| 339 | struct extent_state *state, | 338 | struct extent_state *state, int *bits) |
| 340 | unsigned long bits) | ||
| 341 | { | 339 | { |
| 342 | if (tree->ops && tree->ops->set_bit_hook) { | 340 | if (tree->ops && tree->ops->set_bit_hook) { |
| 343 | return tree->ops->set_bit_hook(tree->mapping->host, | 341 | return tree->ops->set_bit_hook(tree->mapping->host, |
| 344 | state->start, state->end, | 342 | state, bits); |
| 345 | state->state, bits); | ||
| 346 | } | 343 | } |
| 347 | 344 | ||
| 348 | return 0; | 345 | return 0; |
| 349 | } | 346 | } |
| 350 | 347 | ||
| 351 | static void clear_state_cb(struct extent_io_tree *tree, | 348 | static void clear_state_cb(struct extent_io_tree *tree, |
| 352 | struct extent_state *state, | 349 | struct extent_state *state, int *bits) |
| 353 | unsigned long bits) | ||
| 354 | { | 350 | { |
| 355 | if (tree->ops && tree->ops->clear_bit_hook) | 351 | if (tree->ops && tree->ops->clear_bit_hook) |
| 356 | tree->ops->clear_bit_hook(tree->mapping->host, state, bits); | 352 | tree->ops->clear_bit_hook(tree->mapping->host, state, bits); |
| @@ -368,9 +364,10 @@ static void clear_state_cb(struct extent_io_tree *tree, | |||
| 368 | */ | 364 | */ |
| 369 | static int insert_state(struct extent_io_tree *tree, | 365 | static int insert_state(struct extent_io_tree *tree, |
| 370 | struct extent_state *state, u64 start, u64 end, | 366 | struct extent_state *state, u64 start, u64 end, |
| 371 | int bits) | 367 | int *bits) |
| 372 | { | 368 | { |
| 373 | struct rb_node *node; | 369 | struct rb_node *node; |
| 370 | int bits_to_set = *bits & ~EXTENT_CTLBITS; | ||
| 374 | int ret; | 371 | int ret; |
| 375 | 372 | ||
| 376 | if (end < start) { | 373 | if (end < start) { |
| @@ -385,9 +382,9 @@ static int insert_state(struct extent_io_tree *tree, | |||
| 385 | if (ret) | 382 | if (ret) |
| 386 | return ret; | 383 | return ret; |
| 387 | 384 | ||
| 388 | if (bits & EXTENT_DIRTY) | 385 | if (bits_to_set & EXTENT_DIRTY) |
| 389 | tree->dirty_bytes += end - start + 1; | 386 | tree->dirty_bytes += end - start + 1; |
| 390 | state->state |= bits; | 387 | state->state |= bits_to_set; |
| 391 | node = tree_insert(&tree->state, end, &state->rb_node); | 388 | node = tree_insert(&tree->state, end, &state->rb_node); |
| 392 | if (node) { | 389 | if (node) { |
| 393 | struct extent_state *found; | 390 | struct extent_state *found; |
| @@ -457,13 +454,13 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig, | |||
| 457 | * struct is freed and removed from the tree | 454 | * struct is freed and removed from the tree |
| 458 | */ | 455 | */ |
| 459 | static int clear_state_bit(struct extent_io_tree *tree, | 456 | static int clear_state_bit(struct extent_io_tree *tree, |
| 460 | struct extent_state *state, int bits, int wake, | 457 | struct extent_state *state, |
| 461 | int delete) | 458 | int *bits, int wake) |
| 462 | { | 459 | { |
| 463 | int bits_to_clear = bits & ~EXTENT_DO_ACCOUNTING; | 460 | int bits_to_clear = *bits & ~EXTENT_CTLBITS; |
| 464 | int ret = state->state & bits_to_clear; | 461 | int ret = state->state & bits_to_clear; |
| 465 | 462 | ||
| 466 | if ((bits & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) { | 463 | if ((bits_to_clear & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) { |
| 467 | u64 range = state->end - state->start + 1; | 464 | u64 range = state->end - state->start + 1; |
| 468 | WARN_ON(range > tree->dirty_bytes); | 465 | WARN_ON(range > tree->dirty_bytes); |
| 469 | tree->dirty_bytes -= range; | 466 | tree->dirty_bytes -= range; |
| @@ -472,9 +469,8 @@ static int clear_state_bit(struct extent_io_tree *tree, | |||
| 472 | state->state &= ~bits_to_clear; | 469 | state->state &= ~bits_to_clear; |
| 473 | if (wake) | 470 | if (wake) |
| 474 | wake_up(&state->wq); | 471 | wake_up(&state->wq); |
| 475 | if (delete || state->state == 0) { | 472 | if (state->state == 0) { |
| 476 | if (state->tree) { | 473 | if (state->tree) { |
| 477 | clear_state_cb(tree, state, state->state); | ||
| 478 | rb_erase(&state->rb_node, &tree->state); | 474 | rb_erase(&state->rb_node, &tree->state); |
| 479 | state->tree = NULL; | 475 | state->tree = NULL; |
| 480 | free_extent_state(state); | 476 | free_extent_state(state); |
| @@ -515,6 +511,10 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, | |||
| 515 | int set = 0; | 511 | int set = 0; |
| 516 | int clear = 0; | 512 | int clear = 0; |
| 517 | 513 | ||
| 514 | if (delete) | ||
| 515 | bits |= ~EXTENT_CTLBITS; | ||
| 516 | bits |= EXTENT_FIRST_DELALLOC; | ||
| 517 | |||
| 518 | if (bits & (EXTENT_IOBITS | EXTENT_BOUNDARY)) | 518 | if (bits & (EXTENT_IOBITS | EXTENT_BOUNDARY)) |
| 519 | clear = 1; | 519 | clear = 1; |
| 520 | again: | 520 | again: |
| @@ -581,8 +581,7 @@ hit_next: | |||
| 581 | if (err) | 581 | if (err) |
| 582 | goto out; | 582 | goto out; |
| 583 | if (state->end <= end) { | 583 | if (state->end <= end) { |
| 584 | set |= clear_state_bit(tree, state, bits, wake, | 584 | set |= clear_state_bit(tree, state, &bits, wake); |
| 585 | delete); | ||
| 586 | if (last_end == (u64)-1) | 585 | if (last_end == (u64)-1) |
| 587 | goto out; | 586 | goto out; |
| 588 | start = last_end + 1; | 587 | start = last_end + 1; |
| @@ -603,7 +602,7 @@ hit_next: | |||
| 603 | if (wake) | 602 | if (wake) |
| 604 | wake_up(&state->wq); | 603 | wake_up(&state->wq); |
| 605 | 604 | ||
| 606 | set |= clear_state_bit(tree, prealloc, bits, wake, delete); | 605 | set |= clear_state_bit(tree, prealloc, &bits, wake); |
| 607 | 606 | ||
| 608 | prealloc = NULL; | 607 | prealloc = NULL; |
| 609 | goto out; | 608 | goto out; |
| @@ -614,7 +613,7 @@ hit_next: | |||
| 614 | else | 613 | else |
| 615 | next_node = NULL; | 614 | next_node = NULL; |
| 616 | 615 | ||
| 617 | set |= clear_state_bit(tree, state, bits, wake, delete); | 616 | set |= clear_state_bit(tree, state, &bits, wake); |
| 618 | if (last_end == (u64)-1) | 617 | if (last_end == (u64)-1) |
| 619 | goto out; | 618 | goto out; |
| 620 | start = last_end + 1; | 619 | start = last_end + 1; |
| @@ -707,19 +706,19 @@ out: | |||
| 707 | 706 | ||
| 708 | static int set_state_bits(struct extent_io_tree *tree, | 707 | static int set_state_bits(struct extent_io_tree *tree, |
| 709 | struct extent_state *state, | 708 | struct extent_state *state, |
| 710 | int bits) | 709 | int *bits) |
| 711 | { | 710 | { |
| 712 | int ret; | 711 | int ret; |
| 712 | int bits_to_set = *bits & ~EXTENT_CTLBITS; | ||
| 713 | 713 | ||
| 714 | ret = set_state_cb(tree, state, bits); | 714 | ret = set_state_cb(tree, state, bits); |
| 715 | if (ret) | 715 | if (ret) |
| 716 | return ret; | 716 | return ret; |
| 717 | 717 | if ((bits_to_set & EXTENT_DIRTY) && !(state->state & EXTENT_DIRTY)) { | |
| 718 | if ((bits & EXTENT_DIRTY) && !(state->state & EXTENT_DIRTY)) { | ||
| 719 | u64 range = state->end - state->start + 1; | 718 | u64 range = state->end - state->start + 1; |
| 720 | tree->dirty_bytes += range; | 719 | tree->dirty_bytes += range; |
| 721 | } | 720 | } |
| 722 | state->state |= bits; | 721 | state->state |= bits_to_set; |
| 723 | 722 | ||
| 724 | return 0; | 723 | return 0; |
| 725 | } | 724 | } |
| @@ -746,10 +745,9 @@ static void cache_state(struct extent_state *state, | |||
| 746 | * [start, end] is inclusive This takes the tree lock. | 745 | * [start, end] is inclusive This takes the tree lock. |
| 747 | */ | 746 | */ |
| 748 | 747 | ||
| 749 | 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, |
| 750 | int bits, int exclusive_bits, u64 *failed_start, | 749 | int bits, int exclusive_bits, u64 *failed_start, |
| 751 | struct extent_state **cached_state, | 750 | struct extent_state **cached_state, gfp_t mask) |
| 752 | gfp_t mask) | ||
| 753 | { | 751 | { |
| 754 | struct extent_state *state; | 752 | struct extent_state *state; |
| 755 | struct extent_state *prealloc = NULL; | 753 | struct extent_state *prealloc = NULL; |
| @@ -758,6 +756,7 @@ static int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, | |||
| 758 | u64 last_start; | 756 | u64 last_start; |
| 759 | u64 last_end; | 757 | u64 last_end; |
| 760 | 758 | ||
| 759 | bits |= EXTENT_FIRST_DELALLOC; | ||
| 761 | again: | 760 | again: |
| 762 | if (!prealloc && (mask & __GFP_WAIT)) { | 761 | if (!prealloc && (mask & __GFP_WAIT)) { |
| 763 | prealloc = alloc_extent_state(mask); | 762 | prealloc = alloc_extent_state(mask); |
| @@ -779,7 +778,7 @@ again: | |||
| 779 | */ | 778 | */ |
| 780 | node = tree_search(tree, start); | 779 | node = tree_search(tree, start); |
| 781 | if (!node) { | 780 | if (!node) { |
| 782 | err = insert_state(tree, prealloc, start, end, bits); | 781 | err = insert_state(tree, prealloc, start, end, &bits); |
| 783 | prealloc = NULL; | 782 | prealloc = NULL; |
| 784 | BUG_ON(err == -EEXIST); | 783 | BUG_ON(err == -EEXIST); |
| 785 | goto out; | 784 | goto out; |
| @@ -803,7 +802,7 @@ hit_next: | |||
| 803 | goto out; | 802 | goto out; |
| 804 | } | 803 | } |
| 805 | 804 | ||
| 806 | err = set_state_bits(tree, state, bits); | 805 | err = set_state_bits(tree, state, &bits); |
| 807 | if (err) | 806 | if (err) |
| 808 | goto out; | 807 | goto out; |
| 809 | 808 | ||
| @@ -853,7 +852,7 @@ hit_next: | |||
| 853 | if (err) | 852 | if (err) |
| 854 | goto out; | 853 | goto out; |
| 855 | if (state->end <= end) { | 854 | if (state->end <= end) { |
| 856 | err = set_state_bits(tree, state, bits); | 855 | err = set_state_bits(tree, state, &bits); |
| 857 | if (err) | 856 | if (err) |
| 858 | goto out; | 857 | goto out; |
| 859 | cache_state(state, cached_state); | 858 | cache_state(state, cached_state); |
| @@ -878,7 +877,7 @@ hit_next: | |||
| 878 | else | 877 | else |
| 879 | this_end = last_start - 1; | 878 | this_end = last_start - 1; |
| 880 | err = insert_state(tree, prealloc, start, this_end, | 879 | err = insert_state(tree, prealloc, start, this_end, |
| 881 | bits); | 880 | &bits); |
| 882 | BUG_ON(err == -EEXIST); | 881 | BUG_ON(err == -EEXIST); |
| 883 | if (err) { | 882 | if (err) { |
| 884 | prealloc = NULL; | 883 | prealloc = NULL; |
| @@ -904,7 +903,7 @@ hit_next: | |||
| 904 | err = split_state(tree, state, prealloc, end + 1); | 903 | err = split_state(tree, state, prealloc, end + 1); |
| 905 | BUG_ON(err == -EEXIST); | 904 | BUG_ON(err == -EEXIST); |
| 906 | 905 | ||
| 907 | err = set_state_bits(tree, prealloc, bits); | 906 | err = set_state_bits(tree, prealloc, &bits); |
| 908 | if (err) { | 907 | if (err) { |
| 909 | prealloc = NULL; | 908 | prealloc = NULL; |
| 910 | goto out; | 909 | goto out; |
| @@ -967,8 +966,7 @@ int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, | |||
| 967 | { | 966 | { |
| 968 | return clear_extent_bit(tree, start, end, | 967 | return clear_extent_bit(tree, start, end, |
| 969 | EXTENT_DIRTY | EXTENT_DELALLOC | | 968 | EXTENT_DIRTY | EXTENT_DELALLOC | |
| 970 | EXTENT_DO_ACCOUNTING, 0, 0, | 969 | EXTENT_DO_ACCOUNTING, 0, 0, NULL, mask); |
| 971 | NULL, mask); | ||
| 972 | } | 970 | } |
| 973 | 971 | ||
| 974 | 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, |
| @@ -1436,9 +1434,6 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
| 1436 | if (op & EXTENT_CLEAR_DELALLOC) | 1434 | if (op & EXTENT_CLEAR_DELALLOC) |
| 1437 | clear_bits |= EXTENT_DELALLOC; | 1435 | clear_bits |= EXTENT_DELALLOC; |
| 1438 | 1436 | ||
| 1439 | if (op & EXTENT_CLEAR_ACCOUNTING) | ||
| 1440 | clear_bits |= EXTENT_DO_ACCOUNTING; | ||
| 1441 | |||
| 1442 | 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); |
| 1443 | if (!(op & (EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY | | 1438 | if (!(op & (EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY | |
| 1444 | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK | | 1439 | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK | |
| @@ -1917,7 +1912,7 @@ static int submit_one_bio(int rw, struct bio *bio, int mirror_num, | |||
| 1917 | 1912 | ||
| 1918 | if (tree->ops && tree->ops->submit_bio_hook) | 1913 | if (tree->ops && tree->ops->submit_bio_hook) |
| 1919 | tree->ops->submit_bio_hook(page->mapping->host, rw, bio, | 1914 | tree->ops->submit_bio_hook(page->mapping->host, rw, bio, |
| 1920 | mirror_num, bio_flags); | 1915 | mirror_num, bio_flags, start); |
| 1921 | else | 1916 | else |
| 1922 | submit_bio(rw, bio); | 1917 | submit_bio(rw, bio); |
| 1923 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) | 1918 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) |
| @@ -2021,6 +2016,7 @@ static int __extent_read_full_page(struct extent_io_tree *tree, | |||
| 2021 | sector_t sector; | 2016 | sector_t sector; |
| 2022 | struct extent_map *em; | 2017 | struct extent_map *em; |
| 2023 | struct block_device *bdev; | 2018 | struct block_device *bdev; |
| 2019 | struct btrfs_ordered_extent *ordered; | ||
| 2024 | int ret; | 2020 | int ret; |
| 2025 | int nr = 0; | 2021 | int nr = 0; |
| 2026 | size_t page_offset = 0; | 2022 | size_t page_offset = 0; |
| @@ -2032,7 +2028,15 @@ static int __extent_read_full_page(struct extent_io_tree *tree, | |||
| 2032 | set_page_extent_mapped(page); | 2028 | set_page_extent_mapped(page); |
| 2033 | 2029 | ||
| 2034 | end = page_end; | 2030 | end = page_end; |
| 2035 | 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 | } | ||
| 2036 | 2040 | ||
| 2037 | if (page->index == last_byte >> PAGE_CACHE_SHIFT) { | 2041 | if (page->index == last_byte >> PAGE_CACHE_SHIFT) { |
| 2038 | char *userpage; | 2042 | char *userpage; |
| @@ -2590,7 +2594,6 @@ int extent_write_full_page(struct extent_io_tree *tree, struct page *page, | |||
| 2590 | .sync_io = wbc->sync_mode == WB_SYNC_ALL, | 2594 | .sync_io = wbc->sync_mode == WB_SYNC_ALL, |
| 2591 | }; | 2595 | }; |
| 2592 | struct writeback_control wbc_writepages = { | 2596 | struct writeback_control wbc_writepages = { |
| 2593 | .bdi = wbc->bdi, | ||
| 2594 | .sync_mode = wbc->sync_mode, | 2597 | .sync_mode = wbc->sync_mode, |
| 2595 | .older_than_this = NULL, | 2598 | .older_than_this = NULL, |
| 2596 | .nr_to_write = 64, | 2599 | .nr_to_write = 64, |
| @@ -2624,7 +2627,6 @@ int extent_write_locked_range(struct extent_io_tree *tree, struct inode *inode, | |||
| 2624 | .sync_io = mode == WB_SYNC_ALL, | 2627 | .sync_io = mode == WB_SYNC_ALL, |
| 2625 | }; | 2628 | }; |
| 2626 | struct writeback_control wbc_writepages = { | 2629 | struct writeback_control wbc_writepages = { |
| 2627 | .bdi = inode->i_mapping->backing_dev_info, | ||
| 2628 | .sync_mode = mode, | 2630 | .sync_mode = mode, |
| 2629 | .older_than_this = NULL, | 2631 | .older_than_this = NULL, |
| 2630 | .nr_to_write = nr_pages * 2, | 2632 | .nr_to_write = nr_pages * 2, |
| @@ -2679,33 +2681,20 @@ int extent_readpages(struct extent_io_tree *tree, | |||
| 2679 | { | 2681 | { |
| 2680 | struct bio *bio = NULL; | 2682 | struct bio *bio = NULL; |
| 2681 | unsigned page_idx; | 2683 | unsigned page_idx; |
| 2682 | struct pagevec pvec; | ||
| 2683 | unsigned long bio_flags = 0; | 2684 | unsigned long bio_flags = 0; |
| 2684 | 2685 | ||
| 2685 | pagevec_init(&pvec, 0); | ||
| 2686 | for (page_idx = 0; page_idx < nr_pages; page_idx++) { | 2686 | for (page_idx = 0; page_idx < nr_pages; page_idx++) { |
| 2687 | struct page *page = list_entry(pages->prev, struct page, lru); | 2687 | struct page *page = list_entry(pages->prev, struct page, lru); |
| 2688 | 2688 | ||
| 2689 | prefetchw(&page->flags); | 2689 | prefetchw(&page->flags); |
| 2690 | list_del(&page->lru); | 2690 | list_del(&page->lru); |
| 2691 | /* | 2691 | if (!add_to_page_cache_lru(page, mapping, |
| 2692 | * what we want to do here is call add_to_page_cache_lru, | ||
| 2693 | * but that isn't exported, so we reproduce it here | ||
| 2694 | */ | ||
| 2695 | if (!add_to_page_cache(page, mapping, | ||
| 2696 | page->index, GFP_KERNEL)) { | 2692 | page->index, GFP_KERNEL)) { |
| 2697 | |||
| 2698 | /* open coding of lru_cache_add, also not exported */ | ||
| 2699 | page_cache_get(page); | ||
| 2700 | if (!pagevec_add(&pvec, page)) | ||
| 2701 | __pagevec_lru_add_file(&pvec); | ||
| 2702 | __extent_read_full_page(tree, page, get_extent, | 2693 | __extent_read_full_page(tree, page, get_extent, |
| 2703 | &bio, 0, &bio_flags); | 2694 | &bio, 0, &bio_flags); |
| 2704 | } | 2695 | } |
| 2705 | page_cache_release(page); | 2696 | page_cache_release(page); |
| 2706 | } | 2697 | } |
| 2707 | if (pagevec_count(&pvec)) | ||
| 2708 | __pagevec_lru_add_file(&pvec); | ||
| 2709 | BUG_ON(!list_empty(pages)); | 2698 | BUG_ON(!list_empty(pages)); |
| 2710 | if (bio) | 2699 | if (bio) |
| 2711 | submit_one_bio(READ, bio, 0, bio_flags); | 2700 | submit_one_bio(READ, bio, 0, bio_flags); |
