diff options
Diffstat (limited to 'fs/btrfs/extent_map.c')
-rw-r--r-- | fs/btrfs/extent_map.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 9d6aefa937c4..f3a384ed700c 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
@@ -1663,6 +1663,13 @@ void set_page_extent_mapped(struct page *page) | |||
1663 | } | 1663 | } |
1664 | } | 1664 | } |
1665 | 1665 | ||
1666 | void set_page_extent_head(struct page *page, unsigned long len) | ||
1667 | { | ||
1668 | WARN_ON(page->private && page->private == EXTENT_PAGE_PRIVATE && | ||
1669 | PageDirty(page)); | ||
1670 | set_page_private(page, EXTENT_PAGE_PRIVATE_FIRST_PAGE | len << 2); | ||
1671 | } | ||
1672 | |||
1666 | /* | 1673 | /* |
1667 | * basic readpage implementation. Locked extent state structs are inserted | 1674 | * basic readpage implementation. Locked extent state structs are inserted |
1668 | * into the tree that are removed when the IO is done (by the end_io | 1675 | * into the tree that are removed when the IO is done (by the end_io |
@@ -2490,8 +2497,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, | |||
2490 | mark_page_accessed(page0); | 2497 | mark_page_accessed(page0); |
2491 | set_page_extent_mapped(page0); | 2498 | set_page_extent_mapped(page0); |
2492 | WARN_ON(!PageUptodate(page0)); | 2499 | WARN_ON(!PageUptodate(page0)); |
2493 | set_page_private(page0, EXTENT_PAGE_PRIVATE_FIRST_PAGE | | 2500 | set_page_extent_head(page0, len); |
2494 | len << 2); | ||
2495 | } else { | 2501 | } else { |
2496 | i = 0; | 2502 | i = 0; |
2497 | } | 2503 | } |
@@ -2505,8 +2511,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, | |||
2505 | mark_page_accessed(p); | 2511 | mark_page_accessed(p); |
2506 | if (i == 0) { | 2512 | if (i == 0) { |
2507 | eb->first_page = p; | 2513 | eb->first_page = p; |
2508 | set_page_private(p, EXTENT_PAGE_PRIVATE_FIRST_PAGE | | 2514 | set_page_extent_head(p, len); |
2509 | len << 2); | ||
2510 | } else { | 2515 | } else { |
2511 | set_page_private(p, EXTENT_PAGE_PRIVATE); | 2516 | set_page_private(p, EXTENT_PAGE_PRIVATE); |
2512 | } | 2517 | } |
@@ -2569,8 +2574,7 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree, | |||
2569 | 2574 | ||
2570 | if (i == 0) { | 2575 | if (i == 0) { |
2571 | eb->first_page = p; | 2576 | eb->first_page = p; |
2572 | set_page_private(p, EXTENT_PAGE_PRIVATE_FIRST_PAGE | | 2577 | set_page_extent_head(p, len); |
2573 | len << 2); | ||
2574 | } else { | 2578 | } else { |
2575 | set_page_private(p, EXTENT_PAGE_PRIVATE); | 2579 | set_page_private(p, EXTENT_PAGE_PRIVATE); |
2576 | } | 2580 | } |
@@ -2643,6 +2647,11 @@ int clear_extent_buffer_dirty(struct extent_map_tree *tree, | |||
2643 | for (i = 0; i < num_pages; i++) { | 2647 | for (i = 0; i < num_pages; i++) { |
2644 | page = extent_buffer_page(eb, i); | 2648 | page = extent_buffer_page(eb, i); |
2645 | lock_page(page); | 2649 | lock_page(page); |
2650 | if (i == 0) | ||
2651 | set_page_extent_head(page, eb->len); | ||
2652 | else | ||
2653 | set_page_private(page, EXTENT_PAGE_PRIVATE); | ||
2654 | |||
2646 | /* | 2655 | /* |
2647 | * if we're on the last page or the first page and the | 2656 | * if we're on the last page or the first page and the |
2648 | * block isn't aligned on a page boundary, do extra checks | 2657 | * block isn't aligned on a page boundary, do extra checks |
@@ -2697,9 +2706,12 @@ int set_extent_buffer_dirty(struct extent_map_tree *tree, | |||
2697 | */ | 2706 | */ |
2698 | if (i == 0) { | 2707 | if (i == 0) { |
2699 | lock_page(page); | 2708 | lock_page(page); |
2700 | set_page_private(page, | 2709 | set_page_extent_head(page, eb->len); |
2701 | EXTENT_PAGE_PRIVATE_FIRST_PAGE | | 2710 | } else if (PagePrivate(page) && |
2702 | eb->len << 2); | 2711 | page->private != EXTENT_PAGE_PRIVATE) { |
2712 | lock_page(page); | ||
2713 | set_page_extent_mapped(page); | ||
2714 | unlock_page(page); | ||
2703 | } | 2715 | } |
2704 | __set_page_dirty_nobuffers(extent_buffer_page(eb, i)); | 2716 | __set_page_dirty_nobuffers(extent_buffer_page(eb, i)); |
2705 | if (i == 0) | 2717 | if (i == 0) |