summaryrefslogtreecommitdiffstats
path: root/fs/nfs/direct.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2020-05-29 20:14:40 +0200
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2020-06-11 19:33:48 +0200
commitba838a75e73f55a780f1ee896b8e3ecb032dba0f (patch)
tree77afff1e2a6b81553cfa3d640411553a473d39d7 /fs/nfs/direct.c
parentSUNRPC: rpc_xprt lifetime events should record xprt->state (diff)
downloadlinux-ba838a75e73f55a780f1ee896b8e3ecb032dba0f.tar.xz
linux-ba838a75e73f55a780f1ee896b8e3ecb032dba0f.zip
NFS: Fix direct WRITE throughput regression
I measured a 50% throughput regression for large direct writes. The observed on-the-wire behavior is that the client sends every NFS WRITE twice: once as an UNSTABLE WRITE plus a COMMIT, and once as a FILE_SYNC WRITE. This is because the nfs_write_match_verf() check in nfs_direct_commit_complete() fails for every WRITE. Buffered writes use nfs_write_completion(), which sets req->wb_verf correctly. Direct writes use nfs_direct_write_completion(), which does not set req->wb_verf at all. This leaves req->wb_verf set to all zeroes for every direct WRITE, and thus nfs_direct_commit_completion() always sets NFS_ODIRECT_RESCHED_WRITES. This fix appears to restore nearly all of the lost performance. Fixes: 1f28476dcb98 ("NFS: Fix O_DIRECT commit verifier handling") Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to '')
-rw-r--r--fs/nfs/direct.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index bb63e2b93ff7..1b79dd5cf661 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -731,6 +731,8 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
nfs_list_remove_request(req);
if (request_commit) {
kref_get(&req->wb_kref);
+ memcpy(&req->wb_verf, &hdr->verf.verifier,
+ sizeof(req->wb_verf));
nfs_mark_request_commit(req, hdr->lseg, &cinfo,
hdr->ds_commit_idx);
}