Commit 97498956 authored by Theodore Ts'o's avatar Theodore Ts'o

ext4: clear the dirty bit for a page in writeback at the last minute

Move when we call clear_page_dirty_for_io() to just before we actually
write the page.  This simplifies the code somewhat, and avoids marking
pages as clean and then needing to remark them as dirty later.
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 4f01b02c
...@@ -2060,7 +2060,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, ...@@ -2060,7 +2060,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
if (nr_pages == 0) if (nr_pages == 0)
break; break;
for (i = 0; i < nr_pages; i++) { for (i = 0; i < nr_pages; i++) {
int commit_write = 0, redirty_page = 0; int commit_write = 0, skip_page = 0;
struct page *page = pvec.pages[i]; struct page *page = pvec.pages[i];
index = page->index; index = page->index;
...@@ -2086,14 +2086,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, ...@@ -2086,14 +2086,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
* If the page does not have buffers (for * If the page does not have buffers (for
* whatever reason), try to create them using * whatever reason), try to create them using
* __block_write_begin. If this fails, * __block_write_begin. If this fails,
* redirty the page and move on. * skip the page and move on.
*/ */
if (!page_has_buffers(page)) { if (!page_has_buffers(page)) {
if (__block_write_begin(page, 0, len, if (__block_write_begin(page, 0, len,
noalloc_get_block_write)) { noalloc_get_block_write)) {
redirty_page: skip_page:
redirty_page_for_writepage(mpd->wbc,
page);
unlock_page(page); unlock_page(page);
continue; continue;
} }
...@@ -2104,7 +2102,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, ...@@ -2104,7 +2102,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
block_start = 0; block_start = 0;
do { do {
if (!bh) if (!bh)
goto redirty_page; goto skip_page;
if (map && (cur_logical >= map->m_lblk) && if (map && (cur_logical >= map->m_lblk) &&
(cur_logical <= (map->m_lblk + (cur_logical <= (map->m_lblk +
(map->m_len - 1)))) { (map->m_len - 1)))) {
...@@ -2120,22 +2118,23 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, ...@@ -2120,22 +2118,23 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
clear_buffer_unwritten(bh); clear_buffer_unwritten(bh);
} }
/* redirty page if block allocation undone */ /* skip page if block allocation undone */
if (buffer_delay(bh) || buffer_unwritten(bh)) if (buffer_delay(bh) || buffer_unwritten(bh))
redirty_page = 1; skip_page = 1;
bh = bh->b_this_page; bh = bh->b_this_page;
block_start += bh->b_size; block_start += bh->b_size;
cur_logical++; cur_logical++;
pblock++; pblock++;
} while (bh != page_bufs); } while (bh != page_bufs);
if (redirty_page) if (skip_page)
goto redirty_page; goto skip_page;
if (commit_write) if (commit_write)
/* mark the buffer_heads as dirty & uptodate */ /* mark the buffer_heads as dirty & uptodate */
block_commit_write(page, 0, len); block_commit_write(page, 0, len);
clear_page_dirty_for_io(page);
/* /*
* Delalloc doesn't support data journalling, * Delalloc doesn't support data journalling,
* but eventually maybe we'll lift this * but eventually maybe we'll lift this
...@@ -2277,9 +2276,8 @@ static void mpage_da_map_and_submit(struct mpage_da_data *mpd) ...@@ -2277,9 +2276,8 @@ static void mpage_da_map_and_submit(struct mpage_da_data *mpd)
err = blks; err = blks;
/* /*
* If get block returns EAGAIN or ENOSPC and there * If get block returns EAGAIN or ENOSPC and there
* appears to be free blocks we will call * appears to be free blocks we will just let
* ext4_writepage() for all of the pages which will * mpage_da_submit_io() unlock all of the pages.
* just redirty the pages.
*/ */
if (err == -EAGAIN) if (err == -EAGAIN)
goto submit_io; goto submit_io;
...@@ -2777,7 +2775,6 @@ static int write_cache_pages_da(struct address_space *mapping, ...@@ -2777,7 +2775,6 @@ static int write_cache_pages_da(struct address_space *mapping,
(PageWriteback(page) && (PageWriteback(page) &&
(wbc->sync_mode == WB_SYNC_NONE)) || (wbc->sync_mode == WB_SYNC_NONE)) ||
unlikely(page->mapping != mapping)) { unlikely(page->mapping != mapping)) {
continue_unlock:
unlock_page(page); unlock_page(page);
continue; continue;
} }
...@@ -2786,8 +2783,6 @@ static int write_cache_pages_da(struct address_space *mapping, ...@@ -2786,8 +2783,6 @@ static int write_cache_pages_da(struct address_space *mapping,
wait_on_page_writeback(page); wait_on_page_writeback(page);
BUG_ON(PageWriteback(page)); BUG_ON(PageWriteback(page));
if (!clear_page_dirty_for_io(page))
goto continue_unlock;
/* /*
* Can we merge this page to current extent? * Can we merge this page to current extent?
...@@ -2803,7 +2798,6 @@ static int write_cache_pages_da(struct address_space *mapping, ...@@ -2803,7 +2798,6 @@ static int write_cache_pages_da(struct address_space *mapping,
/* /*
* skip rest of the page in the page_vec * skip rest of the page in the page_vec
*/ */
redirty_page_for_writepage(wbc, page);
unlock_page(page); unlock_page(page);
goto ret_extent_tail; goto ret_extent_tail;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment