alloc_new:
if (bio == NULL) {
bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9),
- nr_pages, GFP_KERNEL);
+ min_t(int, nr_pages, bio_get_nr_vecs(bdev)),
+ GFP_KERNEL);
if (bio == NULL)
goto confused;
}
struct pagevec pvec;
int nr_pages;
pgoff_t index;
+ pgoff_t end = -1; /* Inclusive */
int scanned = 0;
+ int is_range = 0;
if (wbc->nonblocking && bdi_write_congested(bdi)) {
wbc->encountered_congestion = 1;
index = 0; /* whole-file sweep */
scanned = 1;
}
+ if (wbc->start || wbc->end) {
+ index = wbc->start >> PAGE_CACHE_SHIFT;
+ end = wbc->end >> PAGE_CACHE_SHIFT;
+ is_range = 1;
+ scanned = 1;
+ }
retry:
- while (!done && (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
- PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE))) {
+ while (!done && (index <= end) &&
+ (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
+ PAGECACHE_TAG_DIRTY,
+ min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
unsigned i;
scanned = 1;
lock_page(page);
+ if (unlikely(page->mapping != mapping)) {
+ unlock_page(page);
+ continue;
+ }
+
+ if (unlikely(is_range) && page->index > end) {
+ done = 1;
+ unlock_page(page);
+ continue;
+ }
+
if (wbc->sync_mode != WB_SYNC_NONE)
wait_on_page_writeback(page);
- if (page->mapping != mapping || PageWriteback(page) ||
+ if (PageWriteback(page) ||
!clear_page_dirty_for_io(page)) {
unlock_page(page);
continue;
index = 0;
goto retry;
}
- mapping->writeback_index = index;
+ if (!is_range)
+ mapping->writeback_index = index;
if (bio)
mpage_bio_submit(WRITE, bio);
return ret;