diff options
author | Andrew Morton <akpm@osdl.org> | 2004-08-22 22:59:27 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-08-22 22:59:27 -0700 |
commit | f07812ca2925f6dc6027883ab15891781dba4827 (patch) | |
tree | e12f1eb2d11cb984b9f9c71801e1b0b75cd812bf /fs | |
parent | d4f9d02b9151b9ff87a950ed42220de4f740d27b (diff) | |
download | history-f07812ca2925f6dc6027883ab15891781dba4827.tar.gz |
[PATCH] Writeback page range hint
Modify mpage_writepages to optionally only write back dirty pages within a
specified range in a file (as in the case of O_SYNC). Cheat a little to avoid
changes to prototypes of aops - just put the <start, end> hint into the
writeback_control struct instead. If <start, end> are not set, then default
to writing back all the mapping's dirty pages.
Signed-off-by: Suparna Bhattacharya <suparna@in.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/mpage.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/fs/mpage.c b/fs/mpage.c index 71c7ca3a455de3..7dfc8c53b350a1 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -627,7 +627,9 @@ mpage_writepages(struct address_space *mapping, 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; @@ -645,9 +647,16 @@ mpage_writepages(struct address_space *mapping, 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))) { + PAGECACHE_TAG_DIRTY, + min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) { unsigned i; scanned = 1; @@ -664,10 +673,21 @@ retry: 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; @@ -706,7 +726,8 @@ retry: index = 0; goto retry; } - mapping->writeback_index = index; + if (!is_range) + mapping->writeback_index = index; if (bio) mpage_bio_submit(WRITE, bio); return ret; |