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: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
parent
4f01b02c8c
commit
9749895644
|
@ -2060,7 +2060,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
|
|||
if (nr_pages == 0)
|
||||
break;
|
||||
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];
|
||||
|
||||
index = page->index;
|
||||
|
@ -2086,14 +2086,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
|
|||
* If the page does not have buffers (for
|
||||
* whatever reason), try to create them using
|
||||
* __block_write_begin. If this fails,
|
||||
* redirty the page and move on.
|
||||
* skip the page and move on.
|
||||
*/
|
||||
if (!page_has_buffers(page)) {
|
||||
if (__block_write_begin(page, 0, len,
|
||||
noalloc_get_block_write)) {
|
||||
redirty_page:
|
||||
redirty_page_for_writepage(mpd->wbc,
|
||||
page);
|
||||
skip_page:
|
||||
unlock_page(page);
|
||||
continue;
|
||||
}
|
||||
|
@ -2104,7 +2102,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
|
|||
block_start = 0;
|
||||
do {
|
||||
if (!bh)
|
||||
goto redirty_page;
|
||||
goto skip_page;
|
||||
if (map && (cur_logical >= map->m_lblk) &&
|
||||
(cur_logical <= (map->m_lblk +
|
||||
(map->m_len - 1)))) {
|
||||
|
@ -2120,22 +2118,23 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
|
|||
clear_buffer_unwritten(bh);
|
||||
}
|
||||
|
||||
/* redirty page if block allocation undone */
|
||||
/* skip page if block allocation undone */
|
||||
if (buffer_delay(bh) || buffer_unwritten(bh))
|
||||
redirty_page = 1;
|
||||
skip_page = 1;
|
||||
bh = bh->b_this_page;
|
||||
block_start += bh->b_size;
|
||||
cur_logical++;
|
||||
pblock++;
|
||||
} while (bh != page_bufs);
|
||||
|
||||
if (redirty_page)
|
||||
goto redirty_page;
|
||||
if (skip_page)
|
||||
goto skip_page;
|
||||
|
||||
if (commit_write)
|
||||
/* mark the buffer_heads as dirty & uptodate */
|
||||
block_commit_write(page, 0, len);
|
||||
|
||||
clear_page_dirty_for_io(page);
|
||||
/*
|
||||
* Delalloc doesn't support data journalling,
|
||||
* but eventually maybe we'll lift this
|
||||
|
@ -2277,9 +2276,8 @@ static void mpage_da_map_and_submit(struct mpage_da_data *mpd)
|
|||
err = blks;
|
||||
/*
|
||||
* If get block returns EAGAIN or ENOSPC and there
|
||||
* appears to be free blocks we will call
|
||||
* ext4_writepage() for all of the pages which will
|
||||
* just redirty the pages.
|
||||
* appears to be free blocks we will just let
|
||||
* mpage_da_submit_io() unlock all of the pages.
|
||||
*/
|
||||
if (err == -EAGAIN)
|
||||
goto submit_io;
|
||||
|
@ -2777,7 +2775,6 @@ static int write_cache_pages_da(struct address_space *mapping,
|
|||
(PageWriteback(page) &&
|
||||
(wbc->sync_mode == WB_SYNC_NONE)) ||
|
||||
unlikely(page->mapping != mapping)) {
|
||||
continue_unlock:
|
||||
unlock_page(page);
|
||||
continue;
|
||||
}
|
||||
|
@ -2786,8 +2783,6 @@ static int write_cache_pages_da(struct address_space *mapping,
|
|||
wait_on_page_writeback(page);
|
||||
|
||||
BUG_ON(PageWriteback(page));
|
||||
if (!clear_page_dirty_for_io(page))
|
||||
goto continue_unlock;
|
||||
|
||||
/*
|
||||
* Can we merge this page to current extent?
|
||||
|
@ -2803,7 +2798,6 @@ static int write_cache_pages_da(struct address_space *mapping,
|
|||
/*
|
||||
* skip rest of the page in the page_vec
|
||||
*/
|
||||
redirty_page_for_writepage(wbc, page);
|
||||
unlock_page(page);
|
||||
goto ret_extent_tail;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue