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
1 changed files with 11 additions and 17 deletions
|
@ -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,
|
||||||
* 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,
|
||||||
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,
|
||||||
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)
|
||||||
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,
|
||||||
(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,
|
||||||
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,
|
||||||
/*
|
/*
|
||||||
* 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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue