From: Trond Myklebust Date: Wed, 25 Jul 2007 14:09:54 -0400 NFS: Writeback optimisation Schedule writes using WB_SYNC_NONE first, then come back for a second pass using WB_SYNC_ALL. Signed-off-by: Trond Myklebust --- fs/nfs/write.c | 32 ++++++++++++++++++++++---------- 1 files changed, 22 insertions(+), 10 deletions(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 75adb8e..b3c5f5d 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1325,21 +1325,14 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr return ret; } -static int nfs_write_mapping(struct address_space *mapping, int how) +static int __nfs_write_mapping(struct address_space *mapping, struct writeback_control *wbc, int how) { - struct writeback_control wbc = { - .bdi = mapping->backing_dev_info, - .sync_mode = WB_SYNC_ALL, - .nr_to_write = LONG_MAX, - .for_writepages = 1, - .range_cyclic = 1, - }; int ret; - ret = nfs_writepages(mapping, &wbc); + ret = nfs_writepages(mapping, wbc); if (ret < 0) goto out; - ret = nfs_sync_mapping_wait(mapping, &wbc, how); + ret = nfs_sync_mapping_wait(mapping, wbc, how); if (ret < 0) goto out; return 0; @@ -1348,6 +1341,25 @@ out: return ret; } +/* Two pass sync: first using WB_SYNC_NONE, then WB_SYNC_ALL */ +static int nfs_write_mapping(struct address_space *mapping, int how) +{ + struct writeback_control wbc = { + .bdi = mapping->backing_dev_info, + .sync_mode = WB_SYNC_NONE, + .nr_to_write = LONG_MAX, + .for_writepages = 1, + .range_cyclic = 1, + }; + int ret; + + ret = __nfs_write_mapping(mapping, &wbc, how); + if (ret < 0) + return ret; + wbc.sync_mode = WB_SYNC_ALL; + return __nfs_write_mapping(mapping, &wbc, how); +} + /* * flush the inode to disk. */