aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 5d66cb27e422..05a1c42e25bf 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
2107static 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
2348update_nr_written: 2375done_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