|
@@ -1653,35 +1653,39 @@ struct mpage_da_data {
|
|
|
*/
|
|
|
static int mpage_da_submit_io(struct mpage_da_data *mpd)
|
|
|
{
|
|
|
- struct address_space *mapping = mpd->inode->i_mapping;
|
|
|
- int ret = 0, err, nr_pages, i;
|
|
|
- unsigned long index, end;
|
|
|
- struct pagevec pvec;
|
|
|
long pages_skipped;
|
|
|
+ struct pagevec pvec;
|
|
|
+ unsigned long index, end;
|
|
|
+ int ret = 0, err, nr_pages, i;
|
|
|
+ struct inode *inode = mpd->inode;
|
|
|
+ struct address_space *mapping = inode->i_mapping;
|
|
|
|
|
|
BUG_ON(mpd->next_page <= mpd->first_page);
|
|
|
- pagevec_init(&pvec, 0);
|
|
|
+ /*
|
|
|
+ * We need to start from the first_page to the next_page - 1
|
|
|
+ * to make sure we also write the mapped dirty buffer_heads.
|
|
|
+ * If we look at mpd->lbh.b_blocknr we would only be looking
|
|
|
+ * at the currently mapped buffer_heads.
|
|
|
+ */
|
|
|
index = mpd->first_page;
|
|
|
end = mpd->next_page - 1;
|
|
|
|
|
|
+ pagevec_init(&pvec, 0);
|
|
|
while (index <= end) {
|
|
|
- /*
|
|
|
- * We can use PAGECACHE_TAG_DIRTY lookup here because
|
|
|
- * even though we have cleared the dirty flag on the page
|
|
|
- * We still keep the page in the radix tree with tag
|
|
|
- * PAGECACHE_TAG_DIRTY. See clear_page_dirty_for_io.
|
|
|
- * The PAGECACHE_TAG_DIRTY is cleared in set_page_writeback
|
|
|
- * which is called via the below writepage callback.
|
|
|
- */
|
|
|
- nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
|
|
|
- PAGECACHE_TAG_DIRTY,
|
|
|
- min(end - index,
|
|
|
- (pgoff_t)PAGEVEC_SIZE-1) + 1);
|
|
|
+ nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE);
|
|
|
if (nr_pages == 0)
|
|
|
break;
|
|
|
for (i = 0; i < nr_pages; i++) {
|
|
|
struct page *page = pvec.pages[i];
|
|
|
|
|
|
+ index = page->index;
|
|
|
+ if (index > end)
|
|
|
+ break;
|
|
|
+ index++;
|
|
|
+
|
|
|
+ BUG_ON(!PageLocked(page));
|
|
|
+ BUG_ON(PageWriteback(page));
|
|
|
+
|
|
|
pages_skipped = mpd->wbc->pages_skipped;
|
|
|
err = mapping->a_ops->writepage(page, mpd->wbc);
|
|
|
if (!err && (pages_skipped == mpd->wbc->pages_skipped))
|
|
@@ -2095,11 +2099,29 @@ static int __mpage_da_writepage(struct page *page,
|
|
|
bh = head;
|
|
|
do {
|
|
|
BUG_ON(buffer_locked(bh));
|
|
|
+ /*
|
|
|
+ * We need to try to allocate
|
|
|
+ * unmapped blocks in the same page.
|
|
|
+ * Otherwise we won't make progress
|
|
|
+ * with the page in ext4_da_writepage
|
|
|
+ */
|
|
|
if (buffer_dirty(bh) &&
|
|
|
(!buffer_mapped(bh) || buffer_delay(bh))) {
|
|
|
mpage_add_bh_to_extent(mpd, logical, bh);
|
|
|
if (mpd->io_done)
|
|
|
return MPAGE_DA_EXTENT_TAIL;
|
|
|
+ } else if (buffer_dirty(bh) && (buffer_mapped(bh))) {
|
|
|
+ /*
|
|
|
+ * mapped dirty buffer. We need to update
|
|
|
+ * the b_state because we look at
|
|
|
+ * b_state in mpage_da_map_blocks. We don't
|
|
|
+ * update b_size because if we find an
|
|
|
+ * unmapped buffer_head later we need to
|
|
|
+ * use the b_state flag of that buffer_head.
|
|
|
+ */
|
|
|
+ if (mpd->lbh.b_size == 0)
|
|
|
+ mpd->lbh.b_state =
|
|
|
+ bh->b_state & BH_FLAGS;
|
|
|
}
|
|
|
logical++;
|
|
|
} while ((bh = bh->b_this_page) != head);
|