diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 658c4a7f2578..cbd2ca99d113 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2439,6 +2439,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2439 | int no_nrwrite_index_update; | 2439 | int no_nrwrite_index_update; |
2440 | int pages_written = 0; | 2440 | int pages_written = 0; |
2441 | long pages_skipped; | 2441 | long pages_skipped; |
2442 | int range_cyclic, cycled = 1, io_done = 0; | ||
2442 | int needed_blocks, ret = 0, nr_to_writebump = 0; | 2443 | int needed_blocks, ret = 0, nr_to_writebump = 0; |
2443 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); | 2444 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); |
2444 | 2445 | ||
@@ -2490,9 +2491,15 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2490 | if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) | 2491 | if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) |
2491 | range_whole = 1; | 2492 | range_whole = 1; |
2492 | 2493 | ||
2493 | if (wbc->range_cyclic) | 2494 | range_cyclic = wbc->range_cyclic; |
2495 | if (wbc->range_cyclic) { | ||
2494 | index = mapping->writeback_index; | 2496 | index = mapping->writeback_index; |
2495 | else | 2497 | if (index) |
2498 | cycled = 0; | ||
2499 | wbc->range_start = index << PAGE_CACHE_SHIFT; | ||
2500 | wbc->range_end = LLONG_MAX; | ||
2501 | wbc->range_cyclic = 0; | ||
2502 | } else | ||
2496 | index = wbc->range_start >> PAGE_CACHE_SHIFT; | 2503 | index = wbc->range_start >> PAGE_CACHE_SHIFT; |
2497 | 2504 | ||
2498 | mpd.wbc = wbc; | 2505 | mpd.wbc = wbc; |
@@ -2506,6 +2513,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2506 | wbc->no_nrwrite_index_update = 1; | 2513 | wbc->no_nrwrite_index_update = 1; |
2507 | pages_skipped = wbc->pages_skipped; | 2514 | pages_skipped = wbc->pages_skipped; |
2508 | 2515 | ||
2516 | retry: | ||
2509 | while (!ret && wbc->nr_to_write > 0) { | 2517 | while (!ret && wbc->nr_to_write > 0) { |
2510 | 2518 | ||
2511 | /* | 2519 | /* |
@@ -2548,6 +2556,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2548 | pages_written += mpd.pages_written; | 2556 | pages_written += mpd.pages_written; |
2549 | wbc->pages_skipped = pages_skipped; | 2557 | wbc->pages_skipped = pages_skipped; |
2550 | ret = 0; | 2558 | ret = 0; |
2559 | io_done = 1; | ||
2551 | } else if (wbc->nr_to_write) | 2560 | } else if (wbc->nr_to_write) |
2552 | /* | 2561 | /* |
2553 | * There is no more writeout needed | 2562 | * There is no more writeout needed |
@@ -2556,6 +2565,13 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2556 | */ | 2565 | */ |
2557 | break; | 2566 | break; |
2558 | } | 2567 | } |
2568 | if (!io_done && !cycled) { | ||
2569 | cycled = 1; | ||
2570 | index = 0; | ||
2571 | wbc->range_start = index << PAGE_CACHE_SHIFT; | ||
2572 | wbc->range_end = mapping->writeback_index - 1; | ||
2573 | goto retry; | ||
2574 | } | ||
2559 | if (pages_skipped != wbc->pages_skipped) | 2575 | if (pages_skipped != wbc->pages_skipped) |
2560 | printk(KERN_EMERG "This should not happen leaving %s " | 2576 | printk(KERN_EMERG "This should not happen leaving %s " |
2561 | "with nr_to_write = %ld ret = %d\n", | 2577 | "with nr_to_write = %ld ret = %d\n", |
@@ -2563,6 +2579,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2563 | 2579 | ||
2564 | /* Update index */ | 2580 | /* Update index */ |
2565 | index += pages_written; | 2581 | index += pages_written; |
2582 | wbc->range_cyclic = range_cyclic; | ||
2566 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) | 2583 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) |
2567 | /* | 2584 | /* |
2568 | * set the writeback_index so that range_cyclic | 2585 | * set the writeback_index so that range_cyclic |