diff options
| -rw-r--r-- | fs/btrfs/extent_io.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 5d66cb27e42..05a1c42e25b 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -2104,6 +2104,16 @@ int extent_read_full_page(struct extent_io_tree *tree, struct page *page, | |||
| 2104 | return ret; | 2104 | return ret; |
| 2105 | } | 2105 | } |
| 2106 | 2106 | ||
| 2107 | static noinline void update_nr_written(struct page *page, | ||
| 2108 | struct writeback_control *wbc, | ||
| 2109 | unsigned long nr_written) | ||
| 2110 | { | ||
| 2111 | wbc->nr_to_write -= nr_written; | ||
| 2112 | if (wbc->range_cyclic || (wbc->nr_to_write > 0 && | ||
| 2113 | wbc->range_start == 0 && wbc->range_end == LLONG_MAX)) | ||
| 2114 | page->mapping->writeback_index = page->index + nr_written; | ||
| 2115 | } | ||
| 2116 | |||
| 2107 | /* | 2117 | /* |
| 2108 | * the writepage semantics are similar to regular writepage. extent | 2118 | * the writepage semantics are similar to regular writepage. extent |
| 2109 | * records are inserted to lock ranges in the tree, and as dirty areas | 2119 | * records are inserted to lock ranges in the tree, and as dirty areas |
| @@ -2173,6 +2183,12 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, | |||
| 2173 | delalloc_end = 0; | 2183 | delalloc_end = 0; |
| 2174 | page_started = 0; | 2184 | page_started = 0; |
| 2175 | if (!epd->extent_locked) { | 2185 | if (!epd->extent_locked) { |
| 2186 | /* | ||
| 2187 | * make sure the wbc mapping index is at least updated | ||
| 2188 | * to this page. | ||
| 2189 | */ | ||
| 2190 | update_nr_written(page, wbc, 0); | ||
| 2191 | |||
| 2176 | while (delalloc_end < page_end) { | 2192 | while (delalloc_end < page_end) { |
| 2177 | nr_delalloc = find_lock_delalloc_range(inode, tree, | 2193 | nr_delalloc = find_lock_delalloc_range(inode, tree, |
| 2178 | page, | 2194 | page, |
| @@ -2194,7 +2210,13 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, | |||
| 2194 | */ | 2210 | */ |
| 2195 | if (page_started) { | 2211 | if (page_started) { |
| 2196 | ret = 0; | 2212 | ret = 0; |
| 2197 | goto update_nr_written; | 2213 | /* |
| 2214 | * we've unlocked the page, so we can't update | ||
| 2215 | * the mapping's writeback index, just update | ||
| 2216 | * nr_to_write. | ||
| 2217 | */ | ||
| 2218 | wbc->nr_to_write -= nr_written; | ||
| 2219 | goto done_unlocked; | ||
| 2198 | } | 2220 | } |
| 2199 | } | 2221 | } |
| 2200 | lock_extent(tree, start, page_end, GFP_NOFS); | 2222 | lock_extent(tree, start, page_end, GFP_NOFS); |
| @@ -2207,13 +2229,18 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, | |||
| 2207 | if (ret == -EAGAIN) { | 2229 | if (ret == -EAGAIN) { |
| 2208 | unlock_extent(tree, start, page_end, GFP_NOFS); | 2230 | unlock_extent(tree, start, page_end, GFP_NOFS); |
| 2209 | redirty_page_for_writepage(wbc, page); | 2231 | redirty_page_for_writepage(wbc, page); |
| 2232 | update_nr_written(page, wbc, nr_written); | ||
| 2210 | unlock_page(page); | 2233 | unlock_page(page); |
| 2211 | ret = 0; | 2234 | ret = 0; |
| 2212 | goto update_nr_written; | 2235 | goto done_unlocked; |
| 2213 | } | 2236 | } |
| 2214 | } | 2237 | } |
| 2215 | 2238 | ||
| 2216 | nr_written++; | 2239 | /* |
| 2240 | * we don't want to touch the inode after unlocking the page, | ||
| 2241 | * so we update the mapping writeback index now | ||
| 2242 | */ | ||
| 2243 | update_nr_written(page, wbc, nr_written + 1); | ||
| 2217 | 2244 | ||
| 2218 | end = page_end; | 2245 | end = page_end; |
| 2219 | if (test_range_bit(tree, start, page_end, EXTENT_DELALLOC, 0)) | 2246 | if (test_range_bit(tree, start, page_end, EXTENT_DELALLOC, 0)) |
| @@ -2345,11 +2372,8 @@ done: | |||
| 2345 | unlock_extent(tree, unlock_start, page_end, GFP_NOFS); | 2372 | unlock_extent(tree, unlock_start, page_end, GFP_NOFS); |
| 2346 | unlock_page(page); | 2373 | unlock_page(page); |
| 2347 | 2374 | ||
| 2348 | update_nr_written: | 2375 | done_unlocked: |
| 2349 | wbc->nr_to_write -= nr_written; | 2376 | |
| 2350 | if (wbc->range_cyclic || (wbc->nr_to_write > 0 && | ||
| 2351 | wbc->range_start == 0 && wbc->range_end == LLONG_MAX)) | ||
| 2352 | page->mapping->writeback_index = page->index + nr_written; | ||
| 2353 | return 0; | 2377 | return 0; |
| 2354 | } | 2378 | } |
| 2355 | 2379 | ||
