combine generic_writepages() and mpage_writepages()
Subsystems (3)
PATCH 21/27 combine generic_writepages() and mpage_writepages()
generic_writepages and mpage_writepages are basically identical, except one calls ->writepage() and the other calls mpage_writepage(). This duplication is irritating.
The patch folds generic_writepage() into mpage_writepages(). It does this rather kludgily: if the get_block argument to mpage_writepages() is NULL then use ->writepage().
Can't think of a better way, really - we could go for a fully-blown write_actor_t thing, but that would be overly elaborate and would not allow mpage_writepage() to be inlined inside mpage_writepages(), which is rather desirable.
fs/mpage.c | 55 +++++++++++++++++++++++++-- mm/page-writeback.c | 104 +--------------------------------------------------- 2 files changed, 53 insertions(+), 106 deletions(-)
mm/page-writeback.c renamed from mm/page-writeback.c~consolidate-writepages +3 -101
@@ -19,8 +19,9 @@#include <linux/pagemap.h> #include <linux/writeback.h> #include <linux/init.h> -#include <linux/sysrq.h> +//#include <linux/sysrq.h> #include <linux/backing-dev.h> +#include <linux/mpage.h> /* * The maximum number of pages to writeout in a single bdflush/kupdate
@@ -313,108 +314,9 @@ int generic_vm_writeback(struct page *pa }EXPORT_SYMBOL (generic_vm_writeback); -/** -* generic_writepages - walk the list of dirty pages of the given -* address space and writepage() all of them. -* -* @mapping: address space structure to write -* @nr_to_write: subtract the number of written pages from *@nr_to_write -* -* This is a library function, which implements the writepages() -* address_space_operation. -* -* (The next two paragraphs refer to code which isn't here yet, but they -* explain the presence of address_space.io_pages) -* -* Pages can be moved from clean_pages or locked_pages onto dirty_pages -* at any time - it's not possible to lock against that. So pages which -* have already been added to a BIO may magically reappear on the dirty_pages -* list. And generic_writepages() will again try to lock those pages. -* But I/O has not yet been started against the page. Thus deadlock. -* -* To avoid this, the entire contents of the dirty_pages list are moved -* onto io_pages up-front. We then walk io_pages, locking the -* pages and submitting them for I/O, moving them to locked_pages. -* -* This has the added benefit of preventing a livelock which would otherwise -* occur if pages are being dirtied faster than we can write them out. -* -* If a page is already under I/O, generic_writepages() skips it, even -* if it's dirty. This is desirable behaviour for memory-cleaning writeback, -* but it is INCORRECT for data-integrity system calls such as fsync(). fsync() -* and msync() need to guarentee that all the data which was dirty at the time -* the call was made get new I/O started against them. The way to do this is -* to run filemap_fdatawait() before calling filemap_fdatawrite(). -* -* It's fairly rare for PageWriteback pages to be on ->dirty_pages. It -* means that someone redirtied the page while it was under I/O. -*/ int generic_writepages (struct address_space *mapping,int *nr_to_write) { -int (*writepage)(struct page *) = mapping->a_ops->writepage; -int ret =0 ; -int done =0 ; -int err; - -write_lock (&mapping->page_lock); - -list_splice (&mapping->dirty_pages, &mapping->io_pages); -INIT_LIST_HEAD (&mapping->dirty_pages); - -while (!list_empty (&mapping->io_pages) && !done) { -struct page *page =list_entry (mapping->io_pages.prev, - struct page, list); -list_del (&page->list); -if (PageWriteback (page)) { -if (PageDirty (page)) { -list_add (&page->list, &mapping->dirty_pages); -continue ; - } -list_add (&page->list, &mapping->locked_pages); -continue ; - } -if (!PageDirty (page)) { -list_add (&page->list, &mapping->clean_pages); -continue ; - } -list_add (&page->list, &mapping->locked_pages); -page_cache_get (page); -write_unlock (&mapping->page_lock); -lock_page (page); - -/* It may have been removed from swapcache: check ->mapping */ -if (page->mapping && !PageWriteback (page) && -TestClearPageDirty (page)) { -/* FIXME: batch this up */ -if (!PageActive (page) &&PageLRU (page)) { -spin_lock (&pagemap_lru_lock); -if (!PageActive (page) &&PageLRU (page)) { -list_del (&page->lru); -list_add (&page->lru, &inactive_list); - } -spin_unlock (&pagemap_lru_lock); - } - err =writepage (page); -if (!ret) - ret = err; -if (nr_to_write && --(*nr_to_write) <=0 ) - done =1 ; - }else { -unlock_page (page); - } - -page_cache_release (page); -write_lock (&mapping->page_lock); - } -if (!list_empty (&mapping->io_pages)) { -/* -* Put the rest back, in the correct order. -*/ -list_splice (&mapping->io_pages, mapping->dirty_pages.prev); -INIT_LIST_HEAD (&mapping->io_pages); - } -write_unlock (&mapping->page_lock); -return ret; +return mpage_writepages (mapping, nr_to_write,NULL ); }EXPORT_SYMBOL (generic_writepages);
fs/mpage.c renamed from fs/mpage.c~consolidate-writepages +50 -5
73 lines not on this page · raw message
-