aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2014-09-18 02:09:27 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-09-24 23:23:02 -0400
commite87b4c7a7ac6d895846570dec637744cf7050df3 (patch)
tree9268a48377b2ddb12733d108c099df3be4fd0414 /fs/nfs
parent8478eaa16e701ecfe054b62ec764bc1291b79e19 (diff)
NFS: don't use STABLE writes during writeback.
commit b31268ac793fd300da66b9c28bbf0a200339ab96 FS: Use stable writes when not doing a bulk flush was a bit heavy handed. The particular problem that lead to this patch was that small writes to an O_SYNC file we being written as UNSTABLE writes followed by a commit. This is appropriate for large writes (which require multiple NFS requests) but for small writes (single NFS request), using NFS_FILE_SYNC is more efficient. So that patch causes the code to select between the two methods depending on how many nfs requests get generated. Unfortunately this ends up applying to non O_SYNC writes as well. In particular if you memory-map a file and update random pages, then when they are eventually written out by writeback they will go as NFS_FILE_SYNC. This is inefficient and slows down the application. So: only set FLUSH_COND_STABLE when wbc->sync_mode is WB_SYNC_ALL. With this patch: O_SYNC writes are NFS_FILE_SYNC for single requests, and NFS_UNSTABLE followed by COMMIT for multiple requests Writing immediately before close of fsync follow the same pattern. Non-O_SYNC writes without an fsync of close eventually get flushed out as UNSTABLE and a commit follows eventually as appropriate. Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/write.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 6786873a2901..a623b00530c3 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -242,11 +242,14 @@ static void nfs_mark_uptodate(struct nfs_page *req)
242 242
243static int wb_priority(struct writeback_control *wbc) 243static int wb_priority(struct writeback_control *wbc)
244{ 244{
245 int ret = 0;
245 if (wbc->for_reclaim) 246 if (wbc->for_reclaim)
246 return FLUSH_HIGHPRI | FLUSH_STABLE; 247 return FLUSH_HIGHPRI | FLUSH_STABLE;
248 if (wbc->sync_mode == WB_SYNC_ALL)
249 ret = FLUSH_COND_STABLE;
247 if (wbc->for_kupdate || wbc->for_background) 250 if (wbc->for_kupdate || wbc->for_background)
248 return FLUSH_LOWPRI | FLUSH_COND_STABLE; 251 ret |= FLUSH_LOWPRI;
249 return FLUSH_COND_STABLE; 252 return ret;
250} 253}
251 254
252/* 255/*