]> git.hungrycats.org Git - linux/commitdiff
[PATCH] remove PF_SYNC
authorAndrew Morton <akpm@digeo.com>
Sat, 14 Dec 2002 11:18:17 +0000 (03:18 -0800)
committerJaroslav Kysela <perex@suse.cz>
Sat, 14 Dec 2002 11:18:17 +0000 (03:18 -0800)
current->flags:PF_SYNC was a hack I added because I didn't want to
change all ->writepage implementations.

It's foul.  And it means that if someone happens to run direct page
reclaim within the context of (say) sys_sync, the writepage invokations
from the VM will be treated as "data integrity" operations, not "memory
cleansing" operations, which would cause latency.

So the patch removes PF_SYNC and adds an extra arg to a_ops->writepage.
 It is the `writeback_control' structure which contains the full context
information about why writepage was called.

The initial version of this patch just passed in a bare `int sync', but
the XFS team need more info so they can perform writearound from within
page reclaim.

The patch also adds writeback_control.for_reclaim, so writepage
implementations can inspect that to work out the call context rather
than peeking at current->flags:PF_MEMALLOC.

39 files changed:
Documentation/filesystems/Locking
Documentation/filesystems/vfs.txt
drivers/mtd/devices/blkmtd.c
fs/adfs/inode.c
fs/affs/file.c
fs/bfs/file.c
fs/block_dev.c
fs/buffer.c
fs/cifs/file.c
fs/ext2/inode.c
fs/ext3/inode.c
fs/fat/inode.c
fs/hfs/inode.c
fs/hpfs/file.c
fs/jfs/inode.c
fs/minix/inode.c
fs/mpage.c
fs/nfs/write.c
fs/ntfs/aops.c
fs/qnx4/inode.c
fs/reiserfs/inode.c
fs/smbfs/file.c
fs/sysv/itree.c
fs/udf/file.c
fs/udf/inode.c
fs/ufs/inode.c
fs/xfs/linux/xfs_aops.c
include/linux/buffer_head.h
include/linux/fs.h
include/linux/nfs_fs.h
include/linux/sched.h
include/linux/swap.h
include/linux/writeback.h
mm/filemap.c
mm/page-writeback.c
mm/page_io.c
mm/shmem.c
mm/swapfile.c
mm/vmscan.c

index 66d727bb9ce770ebddfb6888672fe5f6a4095fa2..fa7c6091b5d25bbab3d4f5232e03d5856f9e2396 100644 (file)
@@ -133,10 +133,10 @@ unlocks and drops the reference.
 
 --------------------------- address_space_operations --------------------------
 prototypes:
-       int (*writepage)(struct page *);
+       int (*writepage)(struct page *page, struct writeback_control *wbc);
        int (*readpage)(struct file *, struct page *);
        int (*sync_page)(struct page *);
-       int (*writepages)(struct address_space *, int *nr_to_write);
+       int (*writepages)(struct address_space *, struct writeback_control *);
        int (*set_page_dirty)(struct page *page);
        int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
        int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
@@ -172,15 +172,16 @@ I/O against them.  They come unlocked upon I/O completion.
 
        ->writepage() is used for two purposes: for "memory cleansing" and for
 "sync".  These are quite different operations and the behaviour may differ
-depending upon the mode.  (Yes, there should be two a_ops for this, or
-writepage should take a writeback_control*)
+depending upon the mode.
 
-If writepage is called for sync (current->flags & PF_SYNC) then it *must*
-write the page, even if that would involve blocking on in-progress I/O.
+If writepage is called for sync (wbc->sync_mode != WBC_SYNC_NONE) then
+it *must* start I/O against the page, even if that would involve
+blocking on in-progress I/O.
 
-If writepage is called for memory cleansing (!(current->flags & PF_SYNC))
-then its role is to get as much writeout underway as possible.  So writepage
-should try to avoid blocking against currently-in-progress I/O.
+If writepage is called for memory cleansing (sync_mode ==
+WBC_SYNC_NONE) then its role is to get as much writeout underway as
+possible.  So writepage should try to avoid blocking against
+currently-in-progress I/O.
 
 If the filesystem is not called for "sync" and it determines that it
 would need to block against in-progress I/O to be able to start new I/O
index 09c219cfb2841670f0ea82084fbc6c5fc183d3c5..ab67bdd0f6dce7df04fa8431fdff315edd495d29 100644 (file)
@@ -264,7 +264,7 @@ struct inode_operations {
        int (*readlink) (struct dentry *, char *,int);
        struct dentry * (*follow_link) (struct dentry *, struct dentry *);
        int (*readpage) (struct file *, struct page *);
-       int (*writepage) (struct file *, struct page *);
+       int (*writepage) (struct page *page, struct writeback_control *wbc);
        int (*bmap) (struct inode *,int);
        void (*truncate) (struct inode *);
        int (*permission) (struct inode *, int);
index 39f09c9c00399b3bf3a884f48d58b937942b2f83..4b9c704fd737dd34c21ead60e826269b0a1b4903 100644 (file)
@@ -151,9 +151,10 @@ MODULE_PARM(wqs, "i");
 /* Page cache stuff */
 
 /* writepage() - should never be called - catch it anyway */
-static int blkmtd_writepage(struct page *page)
+static int blkmtd_writepage(struct page *page, struct writeback_control *wbc)
 {
   printk("blkmtd: writepage called!!!\n");
+  unlock_page(page);
   return -EIO;
 }
 
index b139e7a1f8d0d575a8b7987ab672e2a69e796dd8..c1a4bf8d7bb848092f3e47085cb35e90720f631f 100644 (file)
@@ -51,9 +51,9 @@ abort_toobig:
        return 0;
 }
 
-static int adfs_writepage(struct page *page)
+static int adfs_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page, adfs_get_block);
+       return block_write_full_page(page, adfs_get_block, wbc);
 }
 
 static int adfs_readpage(struct file *file, struct page *page)
index 8db6f186a42b04240e6ca37fffafabe01e7dd254..93c545e071ca81d664f26236773ba8acf142d780 100644 (file)
@@ -407,9 +407,9 @@ err_alloc:
        return -ENOSPC;
 }
 
-static int affs_writepage(struct page *page)
+static int affs_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page, affs_get_block);
+       return block_write_full_page(page, affs_get_block, wbc);
 }
 static int affs_readpage(struct file *file, struct page *page)
 {
index 8f8dbde4636f9ad2d279c2d7b0561ee2075e9a40..747fd1ea55e0c20e8ae2c7f7044b88af8710af87 100644 (file)
@@ -130,9 +130,9 @@ out:
        return err;
 }
 
-static int bfs_writepage(struct page *page)
+static int bfs_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page, bfs_get_block);
+       return block_write_full_page(page, bfs_get_block, wbc);
 }
 
 static int bfs_readpage(struct file *file, struct page *page)
index 02ab290420360efbf9f0d542752d9f53830dad02..8715fead51013c5dea60e5799e3d543684b2f669 100644 (file)
@@ -126,9 +126,9 @@ blkdev_direct_IO(int rw, struct file *file, const struct iovec *iov,
                                nr_segs, blkdev_get_blocks);
 }
 
-static int blkdev_writepage(struct page * page)
+static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page, blkdev_get_block);
+       return block_write_full_page(page, blkdev_get_block, wbc);
 }
 
 static int blkdev_readpage(struct file * file, struct page * page)
index 3de883fc5009b3240e3daab78d582dc576c84d4d..f8018f4eef92c88afdacb4d313c6fa86721a0c7c 100644 (file)
@@ -1632,8 +1632,8 @@ EXPORT_SYMBOL(unmap_underlying_metadata);
  * with submit_bh().  At the address_space level PageWriteback prevents this
  * contention from occurring.
  */
-static int __block_write_full_page(struct inode *inode,
-                       struct page *page, get_block_t *get_block)
+static int __block_write_full_page(struct inode *inode, struct page *page,
+                       get_block_t *get_block, struct writeback_control *wbc)
 {
        int err;
        unsigned long block;
@@ -1705,7 +1705,7 @@ static int __block_write_full_page(struct inode *inode,
        do {
                get_bh(bh);
                if (buffer_mapped(bh) && buffer_dirty(bh)) {
-                       if (called_for_sync()) {
+                       if (wbc->sync_mode != WB_SYNC_NONE) {
                                lock_buffer(bh);
                        } else {
                                if (test_set_buffer_locked(bh)) {
@@ -2485,7 +2485,8 @@ out:
 /*
  * The generic ->writepage function for buffer-backed address_spaces
  */
-int block_write_full_page(struct page *page, get_block_t *get_block)
+int block_write_full_page(struct page *page, get_block_t *get_block,
+                       struct writeback_control *wbc)
 {
        struct inode * const inode = page->mapping->host;
        const unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
@@ -2494,7 +2495,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block)
 
        /* Is the page fully inside i_size? */
        if (page->index < end_index)
-               return __block_write_full_page(inode, page, get_block);
+               return __block_write_full_page(inode, page, get_block, wbc);
 
        /* Is the page fully outside i_size? (truncate in progress) */
        offset = inode->i_size & (PAGE_CACHE_SIZE-1);
@@ -2514,7 +2515,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block)
        memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
        flush_dcache_page(page);
        kunmap_atomic(kaddr, KM_USER0);
-       return __block_write_full_page(inode, page, get_block);
+       return __block_write_full_page(inode, page, get_block, wbc);
 }
 
 sector_t generic_block_bmap(struct address_space *mapping, sector_t block,
index 0984cb20c8264ce5fac4be736832f6a3e27f889b..0e6d0b9515d4f1d3b4f5afd9b38f2610aee999ef 100644 (file)
@@ -415,7 +415,7 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
 }
 
 static int
-cifs_writepage(struct page* page)
+cifs_writepage(struct page* page, struct writeback_control *wbc)
 {
        int rc = -EFAULT;
        int xid;
index 29cccde53b74ef4a8bc033bc466f7717d121f242..f04ec5f0b98eda366aef8dae27a7cfc612de3f05 100644 (file)
@@ -588,9 +588,9 @@ changed:
        goto reread;
 }
 
-static int ext2_writepage(struct page *page)
+static int ext2_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page,ext2_get_block);
+       return block_write_full_page(page, ext2_get_block, wbc);
 }
 
 static int ext2_readpage(struct file *file, struct page *page)
index cf150fed6765c097807b26921f19c3395c84809c..72555eb87b022932616c9d04e9eaa151d92e651d 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/quotaops.h>
 #include <linux/string.h>
 #include <linux/buffer_head.h>
+#include <linux/writeback.h>
 #include <linux/mpage.h>
 #include <linux/uio.h>
 #include "xattr.h"
@@ -1287,7 +1288,7 @@ static int bget_one(handle_t *handle, struct buffer_head *bh)
  * disastrous.  Any write() or metadata operation will sync the fs for
  * us.
  */
-static int ext3_writepage(struct page *page)
+static int ext3_writepage(struct page *page, struct writeback_control *wbc)
 {
        struct inode *inode = page->mapping->host;
        struct buffer_head *page_bufs;
@@ -1308,7 +1309,7 @@ static int ext3_writepage(struct page *page)
                goto out_fail;
 
        needed = ext3_writepage_trans_blocks(inode);
-       if (current->flags & PF_MEMALLOC)
+       if (wbc->for_reclaim)
                handle = ext3_journal_try_start(inode, needed);
        else
                handle = ext3_journal_start(inode, needed);
@@ -1339,7 +1340,7 @@ static int ext3_writepage(struct page *page)
                                PAGE_CACHE_SIZE, NULL, bget_one);
        }
 
-       ret = block_write_full_page(page, ext3_get_block);
+       ret = block_write_full_page(page, ext3_get_block, wbc);
 
        /*
         * The page can become unlocked at any point now, and
index 6ad055bba0b0d6e949fce6a6c2a0d99c38945455..f0e05a3c04e01d17b53e4f45349d6ed56b51c197 100644 (file)
@@ -1050,9 +1050,9 @@ static int is_exec(char *extension)
        return 0;
 }
 
-static int fat_writepage(struct page *page)
+static int fat_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page,fat_get_block);
+       return block_write_full_page(page,fat_get_block, wbc);
 }
 static int fat_readpage(struct file *file, struct page *page)
 {
index b005f18026d9e24d10a8b5d90bf66df7c138f8c8..21f14fcf8ccf6749c74e2c667a27257bc3e095cf 100644 (file)
@@ -229,9 +229,9 @@ int hfs_notify_change_hdr(struct dentry *dentry, struct iattr * attr)
        return __hfs_notify_change(dentry, attr, HFS_HDR);
 }
 
-static int hfs_writepage(struct page *page)
+static int hfs_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page,hfs_get_block);
+       return block_write_full_page(page,hfs_get_block, wbc);
 }
 static int hfs_readpage(struct file *file, struct page *page)
 {
index 4891ce05240795ee1a60c593924ccad4bbbae0d1..5504d729c3dc398e1e67ef452ab31f52c1347fbb 100644 (file)
@@ -98,9 +98,9 @@ int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_
        return 0;
 }
 
-static int hpfs_writepage(struct page *page)
+static int hpfs_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page,hpfs_get_block);
+       return block_write_full_page(page,hpfs_get_block, wbc);
 }
 static int hpfs_readpage(struct file *file, struct page *page)
 {
index 41ffc39e9c54f175d413c610b6aeb98e725a9f50..454b27a20f58ff3e40fe2864950806e1632975ec 100644 (file)
@@ -277,9 +277,9 @@ static int jfs_get_block(struct inode *ip, sector_t lblock,
        return jfs_get_blocks(ip, lblock, 1, bh_result, create);
 }
 
-static int jfs_writepage(struct page *page)
+static int jfs_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page, jfs_get_block);
+       return block_write_full_page(page, jfs_get_block, wbc);
 }
 
 static int jfs_writepages(struct address_space *mapping,
index 18ea5aa41a34dcc722d3d408d6a85f266d81e005..c327d5f03443bae6d106c3ac9bf2c84a10524d19 100644 (file)
@@ -316,9 +316,9 @@ static int minix_get_block(struct inode *inode, sector_t block,
                return V2_minix_get_block(inode, block, bh_result, create);
 }
 
-static int minix_writepage(struct page *page)
+static int minix_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page,minix_get_block);
+       return block_write_full_page(page, minix_get_block, wbc);
 }
 static int minix_readpage(struct file *file, struct page *page)
 {
index 7f3043c7ee9054b76b754e97e57e776de829ddb6..c2e3a2d4e8c443d779d53ca34aeb51247d639c76 100644 (file)
@@ -327,7 +327,7 @@ EXPORT_SYMBOL(mpage_readpage);
  */
 static struct bio *
 mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
-                       sector_t *last_block_in_bio, int *ret)
+       sector_t *last_block_in_bio, int *ret, struct writeback_control *wbc)
 {
        struct inode *inode = page->mapping->host;
        const unsigned blkbits = inode->i_blkbits;
@@ -501,7 +501,7 @@ alloc_new:
 confused:
        if (bio)
                bio = mpage_bio_submit(WRITE, bio);
-       *ret = page->mapping->a_ops->writepage(page);
+       *ret = page->mapping->a_ops->writepage(page, wbc);
 out:
        return bio;
 }
@@ -554,9 +554,8 @@ mpage_writepages(struct address_space *mapping,
        sector_t last_block_in_bio = 0;
        int ret = 0;
        int done = 0;
-       int sync = called_for_sync();
        struct pagevec pvec;
-       int (*writepage)(struct page *);
+       int (*writepage)(struct page *page, struct writeback_control *wbc);
 
        if (wbc->nonblocking && bdi_write_congested(bdi)) {
                blk_run_queues();
@@ -574,7 +573,7 @@ mpage_writepages(struct address_space *mapping,
                struct page *page = list_entry(mapping->io_pages.prev,
                                        struct page, list);
                list_del(&page->list);
-               if (PageWriteback(page) && !sync) {
+               if (PageWriteback(page) && wbc->sync_mode == WB_SYNC_NONE) {
                        if (PageDirty(page)) {
                                list_add(&page->list, &mapping->dirty_pages);
                                continue;
@@ -600,16 +599,16 @@ mpage_writepages(struct address_space *mapping,
 
                lock_page(page);
 
-               if (sync)
+               if (wbc->sync_mode != WB_SYNC_NONE)
                        wait_on_page_writeback(page);
 
                if (page->mapping == mapping && !PageWriteback(page) &&
                                        test_clear_page_dirty(page)) {
                        if (writepage) {
-                               ret = (*writepage)(page);
+                               ret = (*writepage)(page, wbc);
                        } else {
                                bio = mpage_writepage(bio, page, get_block,
-                                               &last_block_in_bio, &ret);
+                                       &last_block_in_bio, &ret, wbc);
                        }
                        if (ret || (--(wbc->nr_to_write) <= 0))
                                done = 1;
index 4849ed704570abd5206efbae58a82e215f605abe..21d30b3a36e6234cc15e50a1fa66e18d867c0a09 100644 (file)
@@ -240,7 +240,7 @@ nfs_writepage_async(struct file *file, struct inode *inode, struct page *page,
  * Write an mmapped page to the server.
  */
 int
-nfs_writepage(struct page *page)
+nfs_writepage(struct page *page, struct writeback_control *wbc)
 {
        struct inode *inode = page->mapping->host;
        unsigned long end_index;
index 1c8703416db6447266e3c1d139d4ff9bb4c5532c..8e80a2be182ab9c256cb83a092819671788dec9f 100644 (file)
@@ -792,7 +792,7 @@ lock_retry_remap:
  *
  * Return 0 on success and -errno on error.
  */
-static int ntfs_writepage(struct page *page)
+static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
 {
        s64 attr_pos;
        struct inode *vi;
index 37ae3c466e7a90f530aa0cfbe11c617d2004369b..616e97433632500edad5f4155ec7433e6818768b 100644 (file)
@@ -424,9 +424,9 @@ static void qnx4_put_super(struct super_block *sb)
        return;
 }
 
-static int qnx4_writepage(struct page *page)
+static int qnx4_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page,qnx4_get_block);
+       return block_write_full_page(page,qnx4_get_block, wbc);
 }
 static int qnx4_readpage(struct file *file, struct page *page)
 {
index 795330017babefd42346e83f8b392868d5003cb3..817c5c465d198c1c242e01e70a51c8c5724b9cc5 100644 (file)
@@ -1917,7 +1917,7 @@ static inline void submit_bh_for_writepage(struct buffer_head **bhp, int nr) {
     }
 }
 
-static int reiserfs_write_full_page(struct page *page) {
+static int reiserfs_write_full_page(struct page *page, struct writeback_control *wbc) {
     struct inode *inode = page->mapping->host ;
     unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT ;
     unsigned last_offset = PAGE_CACHE_SIZE;
@@ -2018,11 +2018,11 @@ static int reiserfs_readpage (struct file *f, struct page * page)
 }
 
 
-static int reiserfs_writepage (struct page * page)
+static int reiserfs_writepage (struct page * page, struct writeback_control *wbc)
 {
     struct inode *inode = page->mapping->host ;
     reiserfs_wait_on_write_block(inode->i_sb) ;
-    return reiserfs_write_full_page(page) ;
+    return reiserfs_write_full_page(page, wbc) ;
 }
 
 
index 9ded6c19c5f1840acf1f47e27a03ecd41daccd96..a174775b2d131ffa355fad44e9af34ec99679123 100644 (file)
@@ -170,7 +170,7 @@ smb_writepage_sync(struct inode *inode, struct page *page,
  * We are called with the page locked and we unlock it when done.
  */
 static int
-smb_writepage(struct page *page)
+smb_writepage(struct page *page, struct writeback_control *wbc)
 {
        struct address_space *mapping = page->mapping;
        struct inode *inode;
index 55e7ff30ed709d514d42043cbc33ff6cc3f7fae4..a1c0b63613515499dfa97f7a8fdac5686828b5c8 100644 (file)
@@ -449,9 +449,9 @@ int sysv_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
        return 0;
 }
 
-static int sysv_writepage(struct page *page)
+static int sysv_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page,get_block);
+       return block_write_full_page(page,get_block,wbc);
 }
 static int sysv_readpage(struct file *file, struct page *page)
 {
index 4c519798fc1bfef04cfbdb2a79425c0b3d911be9..9fd46aff63ae04cec0f4e6526cf77b3a41f1e153 100644 (file)
@@ -62,7 +62,7 @@ static int udf_adinicb_readpage(struct file *file, struct page * page)
        return 0;
 }
 
-static int udf_adinicb_writepage(struct page *page)
+static int udf_adinicb_writepage(struct page *page, struct writeback_control *wbc)
 {
        struct inode *inode = page->mapping->host;
        char *kaddr;
index 24a197a1eeeeeed5766986713808875e161e3d1b..19a6e06cd46e29d3305124e340c74922835a5c96 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/module.h>
 #include <linux/pagemap.h>
 #include <linux/buffer_head.h>
+#include <linux/writeback.h>
 #include <linux/slab.h>
 
 #include "udf_i.h"
@@ -137,9 +138,9 @@ void udf_discard_prealloc(struct inode * inode)
        }
 }
 
-static int udf_writepage(struct page *page)
+static int udf_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page, udf_get_block);
+       return block_write_full_page(page, udf_get_block, wbc);
 }
 
 static int udf_readpage(struct file *file, struct page *page)
@@ -170,6 +171,10 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
 {
        struct page *page;
        char *kaddr;
+       struct writeback_control udf_wbc = {
+               .sync_mode = WB_SYNC_NONE,
+               .nr_to_write = 1,
+       };
 
        /* from now on we have normal address_space methods */
        inode->i_data.a_ops = &udf_aops;
@@ -206,7 +211,7 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
        else
                UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
 
-       inode->i_data.a_ops->writepage(page);
+       inode->i_data.a_ops->writepage(page, &udf_wbc);
        page_cache_release(page);
 
        mark_inode_dirty(inode);
index e9d42f0c2b3fa908ba6af96a1c3320c746be8f9a..615f61a0b88da3951906f22735fa49dba47d259b 100644 (file)
@@ -445,9 +445,9 @@ struct buffer_head * ufs_bread (struct inode * inode, unsigned fragment,
        return NULL;
 }
 
-static int ufs_writepage(struct page *page)
+static int ufs_writepage(struct page *page, struct writeback_control *wbc)
 {
-       return block_write_full_page(page,ufs_getfrag_block);
+       return block_write_full_page(page,ufs_getfrag_block,wbc);
 }
 static int ufs_readpage(struct file *file, struct page *page)
 {
index 3e2bd1679bb82e76042d76e4d11f8ab7d3308065..15b035f67c8f8d3d3f48e15c12ffb45aec922c0f 100644 (file)
@@ -691,7 +691,8 @@ count_page_state(
 
 STATIC int
 linvfs_writepage(
-       struct page             *page)
+       struct page             *page,
+       struct writeback_control *wbc)
 {
        int                     error;
        int                     need_trans = 1;
index 4e7a9bbf99ddf6cf9facd28ec41f4fca13769a7d..e9d6251fa16812833c8283031157e27c08bf6ef5 100644 (file)
@@ -178,7 +178,7 @@ extern int buffer_heads_over_limit;
  */
 int try_to_release_page(struct page * page, int gfp_mask);
 int block_invalidatepage(struct page *page, unsigned long offset);
-int block_write_full_page(struct page*, get_block_t*);
+int block_write_full_page(struct page *page, get_block_t *get_block, struct writeback_control *wbc);
 int block_read_full_page(struct page*, get_block_t*);
 int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
 int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*,
index afbb9474f25bcd2107c30b35c85e35a335a1f8e5..bd133801c3e02d79c8fa6fb93543c1229b97ee06 100644 (file)
@@ -278,7 +278,7 @@ struct address_space;
 struct writeback_control;
 
 struct address_space_operations {
-       int (*writepage)(struct page *);
+       int (*writepage)(struct page *page, struct writeback_control *wbc);
        int (*readpage)(struct file *, struct page *);
        int (*sync_page)(struct page *);
 
index 8d15e17c0b948fb09911d9d44de64a02c50bbe16..2673e32cc4bae39dd8634fa73fc2628299392b48 100644 (file)
@@ -291,7 +291,7 @@ extern void nfs_complete_unlink(struct dentry *);
 /*
  * linux/fs/nfs/write.c
  */
-extern int  nfs_writepage(struct page *);
+extern int  nfs_writepage(struct page *page, struct writeback_control *wbc);
 extern int  nfs_writepages(struct address_space *, struct writeback_control *);
 extern int  nfs_flush_incompatible(struct file *file, struct page *page);
 extern int  nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
index 80a9836df9190aa2b869a8c027cf938a1a844f10..d0726cb87145b6ca466e757e634deb61c703cb0b 100644 (file)
@@ -424,9 +424,8 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
 #define PF_FREEZE      0x00008000      /* this task should be frozen for suspend */
 #define PF_IOTHREAD    0x00010000      /* this thread is needed for doing I/O to swap */
 #define PF_FROZEN      0x00020000      /* frozen for system suspend */
-#define PF_SYNC                0x00040000      /* performing fsync(), etc */
-#define PF_FSTRANS     0x00080000      /* inside a filesystem transaction */
-#define PF_KSWAPD      0x00100000      /* I am kswapd */
+#define PF_FSTRANS     0x00040000      /* inside a filesystem transaction */
+#define PF_KSWAPD      0x00080000      /* I am kswapd */
 
 /*
  * Ptrace flags
index f6b1421f86b084ad884ee12750d0e5e031f6ffc5..c635f392d6c13d7c226207ec3d87aec244880067 100644 (file)
@@ -65,6 +65,7 @@ typedef struct {
 struct sysinfo;
 struct address_space;
 struct zone;
+struct writeback_control;
 
 /*
  * A swap extent maps a range of a swapfile's PAGE_SIZE pages onto a range of
@@ -180,7 +181,7 @@ extern int shmem_unuse(swp_entry_t entry, struct page *page);
 #ifdef CONFIG_SWAP
 /* linux/mm/page_io.c */
 extern int swap_readpage(struct file *, struct page *);
-extern int swap_writepage(struct page *);
+extern int swap_writepage(struct page *page, struct writeback_control *wbc);
 extern int rw_swap_page_sync(int, swp_entry_t, struct page *);
 
 /* linux/mm/swap_state.c */
index 351e5851c04167dc5d7536e1d271fb65c3afc7c2..620f18f5ceeb4542982402077c64bdc519d8d474 100644 (file)
@@ -42,6 +42,7 @@ struct writeback_control {
        int nonblocking;                /* Don't get stuck on request queues */
        int encountered_congestion;     /* An output: a queue is full */
        int for_kupdate;                /* A kupdate writeback */
+       int for_reclaim;                /* Invoked from the page allocator */
 };
 
 /*
@@ -88,13 +89,4 @@ extern int nr_pdflush_threads;       /* Global so it can be exported to sysctl
                                   read-only. */
 
 
-/*
- * Tell the writeback paths that they are being called for a "data integrity"
- * operation such as fsync().
- */
-static inline int called_for_sync(void)
-{
-       return current->flags & PF_SYNC;
-}
-
 #endif         /* WRITEBACK_H */
index 50b05fe9a2e0748ea81a4eab46cec2e2425b5eec..cacecf650277deea1893d53b0221601044fd1e9b 100644 (file)
@@ -117,10 +117,6 @@ static inline int sync_page(struct page *page)
  * cleansing writeback.  The difference between these two operations is that
  * if a dirty page/buffer is encountered, it must be waited upon, and not just
  * skipped over.
- *
- * The PF_SYNC flag is set across this operation and the various functions
- * which care about this distinction must use called_for_sync() to find out
- * which behaviour they should implement.
  */
 int filemap_fdatawrite(struct address_space *mapping)
 {
@@ -133,12 +129,10 @@ int filemap_fdatawrite(struct address_space *mapping)
        if (mapping->backing_dev_info->memory_backed)
                return 0;
 
-       current->flags |= PF_SYNC;
        write_lock(&mapping->page_lock);
        list_splice_init(&mapping->dirty_pages, &mapping->io_pages);
        write_unlock(&mapping->page_lock);
        ret = do_writepages(mapping, &wbc);
-       current->flags &= ~PF_SYNC;
        return ret;
 }
 
index 3880394c8562bdcb8bf4f37ccb7a7b0e7ed222d9..1111f37feb4bdac59c69ee769f7ed61ccf6566ab 100644 (file)
@@ -412,6 +412,9 @@ int write_one_page(struct page *page, int wait)
 {
        struct address_space *mapping = page->mapping;
        int ret = 0;
+       struct writeback_control wbc = {
+               .sync_mode = WB_SYNC_ALL,
+       };
 
        BUG_ON(!PageLocked(page));
 
@@ -424,7 +427,7 @@ int write_one_page(struct page *page, int wait)
                list_add(&page->list, &mapping->locked_pages);
                page_cache_get(page);
                write_unlock(&mapping->page_lock);
-               ret = mapping->a_ops->writepage(page);
+               ret = mapping->a_ops->writepage(page, &wbc);
                if (ret == 0 && wait) {
                        wait_on_page_writeback(page);
                        if (PageError(page))
index 5d3bfdce334fc1527dfb3685d68815627098d9db..faf3e211a33a5167d8f137841d1832994e104d12 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/swapops.h>
 #include <linux/buffer_head.h> /* for block_sync_page() */
 #include <linux/mpage.h>
+#include <linux/writeback.h>
 #include <asm/pgtable.h>
 
 static struct bio *
@@ -86,7 +87,7 @@ static int end_swap_bio_read(struct bio *bio, unsigned int bytes_done, int err)
  * We may have stale swap cache pages in memory: notice
  * them here and get rid of the unnecessary final write.
  */
-int swap_writepage(struct page *page)
+int swap_writepage(struct page *page, struct writeback_control *wbc)
 {
        struct bio *bio;
        int ret = 0;
@@ -143,6 +144,9 @@ struct address_space_operations swap_aops = {
 int rw_swap_page_sync(int rw, swp_entry_t entry, struct page *page)
 {
        int ret;
+       struct writeback_control swap_wbc = {
+               .sync_mode = WB_SYNC_ALL,
+       };
 
        lock_page(page);
 
@@ -154,7 +158,7 @@ int rw_swap_page_sync(int rw, swp_entry_t entry, struct page *page)
                ret = swap_readpage(NULL, page);
                wait_on_page_locked(page);
        } else {
-               ret = swap_writepage(page);
+               ret = swap_writepage(page, &swap_wbc);
                wait_on_page_writeback(page);
        }
        page->mapping = NULL;
index cb8bd154df8f464d80566382bb39fafb00ec35ee..987203cb2a41d8970c3e5f33584a7cb0ce86cff7 100644 (file)
@@ -671,7 +671,7 @@ int shmem_unuse(swp_entry_t entry, struct page *page)
 /*
  * Move the page from the page cache to the swap cache.
  */
-static int shmem_writepage(struct page *page)
+static int shmem_writepage(struct page *page, struct writeback_control *wbc)
 {
        struct shmem_inode_info *info;
        swp_entry_t *entry, swap;
index 0ad388eaf542b73b74b10548377b595cf3b90ba9..067c3095225aa03027d06e93410205b8fc247701 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/shm.h>
 #include <linux/blkdev.h>
 #include <linux/buffer_head.h>
+#include <linux/writeback.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
@@ -696,7 +697,11 @@ static int try_to_unuse(unsigned int type)
                 * and now we must reincrement count to try again later.
                 */
                if ((*swap_map > 1) && PageDirty(page) && PageSwapCache(page)) {
-                       swap_writepage(page);
+                       struct writeback_control wbc = {
+                               .sync_mode = WB_SYNC_NONE,
+                       };
+
+                       swap_writepage(page, &wbc);
                        lock_page(page);
                        wait_on_page_writeback(page);
                }
index 8243646bf5c5573d72f1feece2d60abdf6d2c82b..d2add0ef819d073357319d23e97c8361e3d78cc4 100644 (file)
@@ -319,13 +319,19 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
                                goto keep_locked;
                        if (test_clear_page_dirty(page)) {
                                int res;
+                               struct writeback_control wbc = {
+                                       .sync_mode = WB_SYNC_NONE,
+                                       .nr_to_write = SWAP_CLUSTER_MAX,
+                                       .nonblocking = 1,
+                                       .for_reclaim = 1,
+                               };
 
                                write_lock(&mapping->page_lock);
                                list_move(&page->list, &mapping->locked_pages);
                                write_unlock(&mapping->page_lock);
 
                                SetPageReclaim(page);
-                               res = mapping->a_ops->writepage(page);
+                               res = mapping->a_ops->writepage(page, &wbc);
 
                                if (res == WRITEPAGE_ACTIVATE) {
                                        ClearPageReclaim(page);