diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 03ba20be1329..51cdd13e1c31 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -47,8 +47,10 @@ | |||
47 | static inline int ext4_begin_ordered_truncate(struct inode *inode, | 47 | static inline int ext4_begin_ordered_truncate(struct inode *inode, |
48 | loff_t new_size) | 48 | loff_t new_size) |
49 | { | 49 | { |
50 | return jbd2_journal_begin_ordered_truncate(&EXT4_I(inode)->jinode, | 50 | return jbd2_journal_begin_ordered_truncate( |
51 | new_size); | 51 | EXT4_SB(inode->i_sb)->s_journal, |
52 | &EXT4_I(inode)->jinode, | ||
53 | new_size); | ||
52 | } | 54 | } |
53 | 55 | ||
54 | static void ext4_invalidatepage(struct page *page, unsigned long offset); | 56 | static void ext4_invalidatepage(struct page *page, unsigned long offset); |
@@ -1366,6 +1368,10 @@ retry: | |||
1366 | goto out; | 1368 | goto out; |
1367 | } | 1369 | } |
1368 | 1370 | ||
1371 | /* We cannot recurse into the filesystem as the transaction is already | ||
1372 | * started */ | ||
1373 | flags |= AOP_FLAG_NOFS; | ||
1374 | |||
1369 | page = grab_cache_page_write_begin(mapping, index, flags); | 1375 | page = grab_cache_page_write_begin(mapping, index, flags); |
1370 | if (!page) { | 1376 | if (!page) { |
1371 | ext4_journal_stop(handle); | 1377 | ext4_journal_stop(handle); |
@@ -1375,7 +1381,7 @@ retry: | |||
1375 | *pagep = page; | 1381 | *pagep = page; |
1376 | 1382 | ||
1377 | ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 1383 | ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, |
1378 | ext4_get_block); | 1384 | ext4_get_block); |
1379 | 1385 | ||
1380 | if (!ret && ext4_should_journal_data(inode)) { | 1386 | if (!ret && ext4_should_journal_data(inode)) { |
1381 | ret = walk_page_buffers(handle, page_buffers(page), | 1387 | ret = walk_page_buffers(handle, page_buffers(page), |
@@ -2437,6 +2443,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2437 | int no_nrwrite_index_update; | 2443 | int no_nrwrite_index_update; |
2438 | int pages_written = 0; | 2444 | int pages_written = 0; |
2439 | long pages_skipped; | 2445 | long pages_skipped; |
2446 | int range_cyclic, cycled = 1, io_done = 0; | ||
2440 | int needed_blocks, ret = 0, nr_to_writebump = 0; | 2447 | int needed_blocks, ret = 0, nr_to_writebump = 0; |
2441 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); | 2448 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); |
2442 | 2449 | ||
@@ -2488,9 +2495,15 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2488 | if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) | 2495 | if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) |
2489 | range_whole = 1; | 2496 | range_whole = 1; |
2490 | 2497 | ||
2491 | if (wbc->range_cyclic) | 2498 | range_cyclic = wbc->range_cyclic; |
2499 | if (wbc->range_cyclic) { | ||
2492 | index = mapping->writeback_index; | 2500 | index = mapping->writeback_index; |
2493 | else | 2501 | if (index) |
2502 | cycled = 0; | ||
2503 | wbc->range_start = index << PAGE_CACHE_SHIFT; | ||
2504 | wbc->range_end = LLONG_MAX; | ||
2505 | wbc->range_cyclic = 0; | ||
2506 | } else | ||
2494 | index = wbc->range_start >> PAGE_CACHE_SHIFT; | 2507 | index = wbc->range_start >> PAGE_CACHE_SHIFT; |
2495 | 2508 | ||
2496 | mpd.wbc = wbc; | 2509 | mpd.wbc = wbc; |
@@ -2504,6 +2517,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2504 | wbc->no_nrwrite_index_update = 1; | 2517 | wbc->no_nrwrite_index_update = 1; |
2505 | pages_skipped = wbc->pages_skipped; | 2518 | pages_skipped = wbc->pages_skipped; |
2506 | 2519 | ||
2520 | retry: | ||
2507 | while (!ret && wbc->nr_to_write > 0) { | 2521 | while (!ret && wbc->nr_to_write > 0) { |
2508 | 2522 | ||
2509 | /* | 2523 | /* |
@@ -2546,6 +2560,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2546 | pages_written += mpd.pages_written; | 2560 | pages_written += mpd.pages_written; |
2547 | wbc->pages_skipped = pages_skipped; | 2561 | wbc->pages_skipped = pages_skipped; |
2548 | ret = 0; | 2562 | ret = 0; |
2563 | io_done = 1; | ||
2549 | } else if (wbc->nr_to_write) | 2564 | } else if (wbc->nr_to_write) |
2550 | /* | 2565 | /* |
2551 | * There is no more writeout needed | 2566 | * There is no more writeout needed |
@@ -2554,6 +2569,13 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2554 | */ | 2569 | */ |
2555 | break; | 2570 | break; |
2556 | } | 2571 | } |
2572 | if (!io_done && !cycled) { | ||
2573 | cycled = 1; | ||
2574 | index = 0; | ||
2575 | wbc->range_start = index << PAGE_CACHE_SHIFT; | ||
2576 | wbc->range_end = mapping->writeback_index - 1; | ||
2577 | goto retry; | ||
2578 | } | ||
2557 | if (pages_skipped != wbc->pages_skipped) | 2579 | if (pages_skipped != wbc->pages_skipped) |
2558 | printk(KERN_EMERG "This should not happen leaving %s " | 2580 | printk(KERN_EMERG "This should not happen leaving %s " |
2559 | "with nr_to_write = %ld ret = %d\n", | 2581 | "with nr_to_write = %ld ret = %d\n", |
@@ -2561,6 +2583,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2561 | 2583 | ||
2562 | /* Update index */ | 2584 | /* Update index */ |
2563 | index += pages_written; | 2585 | index += pages_written; |
2586 | wbc->range_cyclic = range_cyclic; | ||
2564 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) | 2587 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) |
2565 | /* | 2588 | /* |
2566 | * set the writeback_index so that range_cyclic | 2589 | * set the writeback_index so that range_cyclic |
@@ -2648,6 +2671,9 @@ retry: | |||
2648 | ret = PTR_ERR(handle); | 2671 | ret = PTR_ERR(handle); |
2649 | goto out; | 2672 | goto out; |
2650 | } | 2673 | } |
2674 | /* We cannot recurse into the filesystem as the transaction is already | ||
2675 | * started */ | ||
2676 | flags |= AOP_FLAG_NOFS; | ||
2651 | 2677 | ||
2652 | page = grab_cache_page_write_begin(mapping, index, flags); | 2678 | page = grab_cache_page_write_begin(mapping, index, flags); |
2653 | if (!page) { | 2679 | if (!page) { |