The patch titled BLOCK: Dissociate generic_writepages() from mpage stuff has been added to the -mm tree. Its filename is block-dissociate-generic_writepages-from-mpage-stuff.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: BLOCK: Dissociate generic_writepages() from mpage stuff From: David Howells <dhowells@xxxxxxxxxx> Dissociate the generic_writepages() function from the mpage stuff, moving its declaration to linux/mm.h and actually emitting a full implementation into mm/page-writeback.c. The implementation is a partial duplicate of mpage_writepages() with all BIO references removed. It is used by NFS to do writeback. Signed-off-by: David Howells <dhowells@xxxxxxxxxx> Cc: Jens Axboe <axboe@xxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- fs/block_dev.c | 1 fs/mpage.c | 2 include/linux/mpage.h | 6 - include/linux/writeback.h | 2 mm/page-writeback.c | 134 ++++++++++++++++++++++++++++++++++++ 5 files changed, 139 insertions(+), 6 deletions(-) diff -puN fs/block_dev.c~block-dissociate-generic_writepages-from-mpage-stuff fs/block_dev.c --- a/fs/block_dev.c~block-dissociate-generic_writepages-from-mpage-stuff +++ a/fs/block_dev.c @@ -17,6 +17,7 @@ #include <linux/module.h> #include <linux/blkpg.h> #include <linux/buffer_head.h> +#include <linux/writeback.h> #include <linux/mpage.h> #include <linux/mount.h> #include <linux/uio.h> diff -puN fs/mpage.c~block-dissociate-generic_writepages-from-mpage-stuff fs/mpage.c --- a/fs/mpage.c~block-dissociate-generic_writepages-from-mpage-stuff +++ a/fs/mpage.c @@ -693,6 +693,8 @@ out: * the call was made get new I/O started against them. If wbc->sync_mode is * WB_SYNC_ALL then we were called for data integrity and we must wait for * existing IO to complete. + * + * If you fix this you should check generic_writepages() also! */ int mpage_writepages(struct address_space *mapping, diff -puN include/linux/mpage.h~block-dissociate-generic_writepages-from-mpage-stuff include/linux/mpage.h --- a/include/linux/mpage.h~block-dissociate-generic_writepages-from-mpage-stuff +++ a/include/linux/mpage.h @@ -20,9 +20,3 @@ int mpage_writepages(struct address_spac struct writeback_control *wbc, get_block_t get_block); int mpage_writepage(struct page *page, get_block_t *get_block, struct writeback_control *wbc); - -static inline int -generic_writepages(struct address_space *mapping, struct writeback_control *wbc) -{ - return mpage_writepages(mapping, wbc, NULL); -} diff -puN include/linux/writeback.h~block-dissociate-generic_writepages-from-mpage-stuff include/linux/writeback.h --- a/include/linux/writeback.h~block-dissociate-generic_writepages-from-mpage-stuff +++ a/include/linux/writeback.h @@ -111,6 +111,8 @@ balance_dirty_pages_ratelimited(struct a } int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0); +extern int generic_writepages(struct address_space *mapping, + struct writeback_control *wbc); int do_writepages(struct address_space *mapping, struct writeback_control *wbc); int sync_page_range(struct inode *inode, struct address_space *mapping, loff_t pos, loff_t count); diff -puN mm/page-writeback.c~block-dissociate-generic_writepages-from-mpage-stuff mm/page-writeback.c --- a/mm/page-writeback.c~block-dissociate-generic_writepages-from-mpage-stuff +++ a/mm/page-writeback.c @@ -23,6 +23,7 @@ #include <linux/backing-dev.h> #include <linux/blkdev.h> #include <linux/buffer_head.h> +#include <linux/pagevec.h> #include <linux/mpage.h> #include <linux/percpu.h> #include <linux/notifier.h> @@ -551,6 +552,139 @@ void __init page_writeback_init(void) register_cpu_notifier(&ratelimit_nb); } +/** + * generic_writepages - walk the list of dirty pages of the given + * address space and writepage() all of them. + * + * @mapping: address space structure to write + * @wbc: subtract the number of written pages from *@wbc->nr_to_write + * + * This is a library function, which implements the writepages() + * address_space_operation. + * + * 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 guarantee that all the data which was dirty at the time + * the call was made get new I/O started against them. If wbc->sync_mode is + * WB_SYNC_ALL then we were called for data integrity and we must wait for + * existing IO to complete. + * + * Derived from mpage_writepages() - if you fix this you should check that + * also! + */ +int generic_writepages(struct address_space *mapping, + struct writeback_control *wbc) +{ + struct backing_dev_info *bdi = mapping->backing_dev_info; + int ret = 0; + int done = 0; + int (*writepage)(struct page *page, struct writeback_control *wbc); + struct pagevec pvec; + int nr_pages; + pgoff_t index; + pgoff_t end; /* Inclusive */ + int scanned = 0; + int range_whole = 0; + + if (wbc->nonblocking && bdi_write_congested(bdi)) { + wbc->encountered_congestion = 1; + return 0; + } + + writepage = mapping->a_ops->writepage; + + /* deal with chardevs and other special file */ + if (!writepage) + return 0; + + pagevec_init(&pvec, 0); + if (wbc->range_cyclic) { + index = mapping->writeback_index; /* Start from prev offset */ + end = -1; + } else { + index = wbc->range_start >> PAGE_CACHE_SHIFT; + end = wbc->range_end >> PAGE_CACHE_SHIFT; + if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) + range_whole = 1; + scanned = 1; + } +retry: + while (!done && (index <= end) && + (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, + PAGECACHE_TAG_DIRTY, + min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) { + unsigned i; + + scanned = 1; + for (i = 0; i < nr_pages; i++) { + struct page *page = pvec.pages[i]; + + /* + * At this point we hold neither mapping->tree_lock nor + * lock on the page itself: the page may be truncated or + * invalidated (changing page->mapping to NULL), or even + * swizzled back from swapper_space to tmpfs file + * mapping + */ + lock_page(page); + + if (unlikely(page->mapping != mapping)) { + unlock_page(page); + continue; + } + + if (!wbc->range_cyclic && page->index > end) { + done = 1; + unlock_page(page); + continue; + } + + if (wbc->sync_mode != WB_SYNC_NONE) + wait_on_page_writeback(page); + + if (PageWriteback(page) || + !clear_page_dirty_for_io(page)) { + unlock_page(page); + continue; + } + + ret = (*writepage)(page, wbc); + if (ret) { + if (ret == -ENOSPC) + set_bit(AS_ENOSPC, &mapping->flags); + else + set_bit(AS_EIO, &mapping->flags); + } + + if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE)) + unlock_page(page); + if (ret || (--(wbc->nr_to_write) <= 0)) + done = 1; + if (wbc->nonblocking && bdi_write_congested(bdi)) { + wbc->encountered_congestion = 1; + done = 1; + } + } + pagevec_release(&pvec); + cond_resched(); + } + if (!scanned && !done) { + /* + * We hit the last page and there is more work to be done: wrap + * back to the start of the file + */ + scanned = 1; + index = 0; + goto retry; + } + if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) + mapping->writeback_index = index; + return ret; +} + +EXPORT_SYMBOL(generic_writepages); + int do_writepages(struct address_space *mapping, struct writeback_control *wbc) { int ret; _ Patches currently in -mm which might be from dhowells@xxxxxxxxxx are git-gfs2.patch git-nfs.patch nfs-replace-null-dentries-that-appear-in-readdirs-list-2.patch binfmt_elf-consistently-use-loff_t.patch afs-add-lock-annotations-to-afs_proc_cell_servers_startstop.patch elf_fdpic_core_dump-dont-take-tasklist_lock.patch simplify-update_times-avoid-jiffies-jiffies_64-aliasing-problem-2.patch lib-rwsemc-un-inline-rwsem_down_failed_common.patch reiserfs-make-sure-all-dentries-refs-are-released-before-calling-kill_block_super-try-2.patch fs-cache-provide-a-filesystem-specific-syncable-page-bit.patch fs-cache-generic-filesystem-caching-facility.patch fs-cache-release-page-private-in-failed-readahead.patch fs-cache-release-page-private-after-failed-readahead-12.patch fs-cache-make-kafs-use-fs-cache.patch fs-cache-make-kafs-use-fs-cache-fix.patch fs-cache-make-kafs-use-fs-cache-12.patch fs-cache-make-kafs-use-fs-cache-12-fix.patch fs-cache-make-kafs-use-fs-cache-vs-streamline-generic_file_-interfaces-and-filemap.patch nfs-use-local-caching.patch nfs-use-local-caching-12.patch nfs-use-local-caching-12-fix.patch fs-cache-cachefiles-ia64-missing-copy_page-export.patch fs-cache-cachefiles-a-cache-that-backs-onto-a-mounted-filesystem.patch fs-cache-cachefiles-a-cache-that-backs-onto-a-mounted-filesystem-cachefiles-printk-format-warning.patch fs-cache-cachefiles-a-cache-that-backs-onto-a-mounted-filesystem-warning-fixes.patch autofs-make-sure-all-dentries-refs-are-released-before-calling-kill_anon_super.patch vfs-destroy-the-dentries-contributed-by-a-superblock-on-unmounting.patch vfs-make-filldir_t-and-struct-kstat-deal-in-64-bit-inode-numbers.patch vfs-make-filldir_t-and-struct-kstat-deal-in-64-bit-inode-numbers-alpha-fix.patch nfs-represent-64-bit-fileids-as-64-bit-inode-numbers-on-32-bit-systems.patch ecryptfs-get_sb_dev-fix.patch block-move-functions-out-of-buffer-code.patch block-remove-duplicate-declaration-of-exit_io_context.patch block-stop-fallback_migrate_page-from-using-page_has_buffers.patch block-separate-the-bounce-buffering-code-from-the-highmem-code.patch block-dont-call-block_sync_page-from-afs.patch block-move-extern-declarations-out-of-fs-c-into-header-files.patch block-move-extern-declarations-out-of-fs-c-into-header-files-tidy.patch block-remove-dependence-on-existence-of-blockdev_superblock.patch block-remove-dependence-on-existence-of-blockdev_superblock-tidy.patch block-dissociate-generic_writepages-from-mpage-stuff.patch block-move-__invalidate_device-to-block_devc.patch block-move-the-loop-device-ioctl-compat-stuff-to-the-loop-driver.patch block-move-common-fs-specific-ioctls-to-linux-fsh.patch block-move-the-reiserfs-device-ioctl-compat-stuff-to-the-reiserfs-driver.patch block-move-the-ext2-device-ioctl-compat-stuff-to-the-ext2-driver.patch block-move-the-ext3-device-ioctl-compat-stuff-to-the-ext3-driver.patch block-move-the-msdos-device-ioctl-compat-stuff-to-the-msdos-driver.patch block-remove-no-longer-necessary-linux-mpageh-inclusions.patch block-remove-no-longer-necessary-linux-buffer_headh-inclusions.patch block-make-usb-storage-depend-on-scsi-rather-than-selecting-it.patch block-make-it-possible-to-disable-the-block-layer.patch block-make-it-possible-to-disable-the-block-layer-tidy.patch block-make-it-possible-to-disable-the-block-layer-tidy-fix.patch reiser4-get_sb_dev-fix.patch mutex-subsystem-synchro-test-module.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html