@@ -1648,14 +1648,14 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd)
1648
1648
int ret = 0 , err , nr_pages , i ;
1649
1649
unsigned long index , end ;
1650
1650
struct pagevec pvec ;
1651
+ long pages_skipped ;
1651
1652
1652
1653
BUG_ON (mpd -> next_page <= mpd -> first_page );
1653
1654
pagevec_init (& pvec , 0 );
1654
1655
index = mpd -> first_page ;
1655
1656
end = mpd -> next_page - 1 ;
1656
1657
1657
1658
while (index <= end ) {
1658
- /* XXX: optimize tail */
1659
1659
/*
1660
1660
* We can use PAGECACHE_TAG_DIRTY lookup here because
1661
1661
* even though we have cleared the dirty flag on the page
@@ -1673,8 +1673,13 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd)
1673
1673
for (i = 0 ; i < nr_pages ; i ++ ) {
1674
1674
struct page * page = pvec .pages [i ];
1675
1675
1676
+ pages_skipped = mpd -> wbc -> pages_skipped ;
1676
1677
err = mapping -> a_ops -> writepage (page , mpd -> wbc );
1677
- if (!err )
1678
+ if (!err && (pages_skipped == mpd -> wbc -> pages_skipped ))
1679
+ /*
1680
+ * have successfully written the page
1681
+ * without skipping the same
1682
+ */
1678
1683
mpd -> pages_written ++ ;
1679
1684
/*
1680
1685
* In error case, we have to continue because
@@ -2110,7 +2115,6 @@ static int mpage_da_writepages(struct address_space *mapping,
2110
2115
struct writeback_control * wbc ,
2111
2116
struct mpage_da_data * mpd )
2112
2117
{
2113
- long to_write ;
2114
2118
int ret ;
2115
2119
2116
2120
if (!mpd -> get_block )
@@ -2125,19 +2129,18 @@ static int mpage_da_writepages(struct address_space *mapping,
2125
2129
mpd -> pages_written = 0 ;
2126
2130
mpd -> retval = 0 ;
2127
2131
2128
- to_write = wbc -> nr_to_write ;
2129
-
2130
2132
ret = write_cache_pages (mapping , wbc , __mpage_da_writepage , mpd );
2131
-
2132
2133
/*
2133
2134
* Handle last extent of pages
2134
2135
*/
2135
2136
if (!mpd -> io_done && mpd -> next_page != mpd -> first_page ) {
2136
2137
if (mpage_da_map_blocks (mpd ) == 0 )
2137
2138
mpage_da_submit_io (mpd );
2138
- }
2139
2139
2140
- wbc -> nr_to_write = to_write - mpd -> pages_written ;
2140
+ mpd -> io_done = 1 ;
2141
+ ret = MPAGE_DA_EXTENT_TAIL ;
2142
+ }
2143
+ wbc -> nr_to_write -= mpd -> pages_written ;
2141
2144
return ret ;
2142
2145
}
2143
2146
@@ -2366,11 +2369,14 @@ static int ext4_da_writepages_trans_blocks(struct inode *inode)
2366
2369
static int ext4_da_writepages (struct address_space * mapping ,
2367
2370
struct writeback_control * wbc )
2368
2371
{
2372
+ pgoff_t index ;
2373
+ int range_whole = 0 ;
2369
2374
handle_t * handle = NULL ;
2370
2375
struct mpage_da_data mpd ;
2371
2376
struct inode * inode = mapping -> host ;
2377
+ int no_nrwrite_index_update ;
2378
+ long pages_written = 0 , pages_skipped ;
2372
2379
int needed_blocks , ret = 0 , nr_to_writebump = 0 ;
2373
- long to_write , pages_skipped = 0 ;
2374
2380
struct ext4_sb_info * sbi = EXT4_SB (mapping -> host -> i_sb );
2375
2381
2376
2382
/*
@@ -2390,16 +2396,26 @@ static int ext4_da_writepages(struct address_space *mapping,
2390
2396
nr_to_writebump = sbi -> s_mb_stream_request - wbc -> nr_to_write ;
2391
2397
wbc -> nr_to_write = sbi -> s_mb_stream_request ;
2392
2398
}
2399
+ if (wbc -> range_start == 0 && wbc -> range_end == LLONG_MAX )
2400
+ range_whole = 1 ;
2393
2401
2394
-
2395
- pages_skipped = wbc -> pages_skipped ;
2402
+ if (wbc -> range_cyclic )
2403
+ index = mapping -> writeback_index ;
2404
+ else
2405
+ index = wbc -> range_start >> PAGE_CACHE_SHIFT ;
2396
2406
2397
2407
mpd .wbc = wbc ;
2398
2408
mpd .inode = mapping -> host ;
2399
2409
2400
- restart_loop :
2401
- to_write = wbc -> nr_to_write ;
2402
- while (!ret && to_write > 0 ) {
2410
+ /*
2411
+ * we don't want write_cache_pages to update
2412
+ * nr_to_write and writeback_index
2413
+ */
2414
+ no_nrwrite_index_update = wbc -> no_nrwrite_index_update ;
2415
+ wbc -> no_nrwrite_index_update = 1 ;
2416
+ pages_skipped = wbc -> pages_skipped ;
2417
+
2418
+ while (!ret && wbc -> nr_to_write > 0 ) {
2403
2419
2404
2420
/*
2405
2421
* we insert one extent at a time. So we need
@@ -2420,46 +2436,53 @@ static int ext4_da_writepages(struct address_space *mapping,
2420
2436
dump_stack ();
2421
2437
goto out_writepages ;
2422
2438
}
2423
- to_write -= wbc -> nr_to_write ;
2424
-
2425
2439
mpd .get_block = ext4_da_get_block_write ;
2426
2440
ret = mpage_da_writepages (mapping , wbc , & mpd );
2427
2441
2428
2442
ext4_journal_stop (handle );
2429
2443
2430
- if (mpd .retval == - ENOSPC )
2444
+ if (mpd .retval == - ENOSPC ) {
2445
+ /* commit the transaction which would
2446
+ * free blocks released in the transaction
2447
+ * and try again
2448
+ */
2431
2449
jbd2_journal_force_commit_nested (sbi -> s_journal );
2432
-
2433
- /* reset the retry count */
2434
- if (ret == MPAGE_DA_EXTENT_TAIL ) {
2450
+ wbc -> pages_skipped = pages_skipped ;
2451
+ ret = 0 ;
2452
+ } else if (ret == MPAGE_DA_EXTENT_TAIL ) {
2435
2453
/*
2436
2454
* got one extent now try with
2437
2455
* rest of the pages
2438
2456
*/
2439
- to_write += wbc -> nr_to_write ;
2457
+ pages_written += mpd .pages_written ;
2458
+ wbc -> pages_skipped = pages_skipped ;
2440
2459
ret = 0 ;
2441
- } else if (wbc -> nr_to_write ) {
2460
+ } else if (wbc -> nr_to_write )
2442
2461
/*
2443
2462
* There is no more writeout needed
2444
2463
* or we requested for a noblocking writeout
2445
2464
* and we found the device congested
2446
2465
*/
2447
- to_write += wbc -> nr_to_write ;
2448
2466
break ;
2449
- }
2450
- wbc -> nr_to_write = to_write ;
2451
- }
2452
-
2453
- if (!wbc -> range_cyclic && (pages_skipped != wbc -> pages_skipped )) {
2454
- /* We skipped pages in this loop */
2455
- wbc -> nr_to_write = to_write +
2456
- wbc -> pages_skipped - pages_skipped ;
2457
- wbc -> pages_skipped = pages_skipped ;
2458
- goto restart_loop ;
2459
2467
}
2468
+ if (pages_skipped != wbc -> pages_skipped )
2469
+ printk (KERN_EMERG "This should not happen leaving %s "
2470
+ "with nr_to_write = %ld ret = %d\n" ,
2471
+ __func__ , wbc -> nr_to_write , ret );
2472
+
2473
+ /* Update index */
2474
+ index += pages_written ;
2475
+ if (wbc -> range_cyclic || (range_whole && wbc -> nr_to_write > 0 ))
2476
+ /*
2477
+ * set the writeback_index so that range_cyclic
2478
+ * mode will write it back later
2479
+ */
2480
+ mapping -> writeback_index = index ;
2460
2481
2461
2482
out_writepages :
2462
- wbc -> nr_to_write = to_write - nr_to_writebump ;
2483
+ if (!no_nrwrite_index_update )
2484
+ wbc -> no_nrwrite_index_update = 0 ;
2485
+ wbc -> nr_to_write -= nr_to_writebump ;
2463
2486
return ret ;
2464
2487
}
2465
2488
0 commit comments