summaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-03-21 21:19:41 +0100
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-04-19 22:53:20 +0200
commit1e799b673c6b82b336ab13c48b5651d511ca3000 (patch)
tree9954155b2a9bdd72e49a078418ceea6c47bcc609 /net/sunrpc/xprt.c
parentNFSv4: Only increment the sequence id if the server saw it (diff)
downloadlinux-1e799b673c6b82b336ab13c48b5651d511ca3000.tar.xz
linux-1e799b673c6b82b336ab13c48b5651d511ca3000.zip
SUNRPC: Fix read ordering problems with req->rq_private_buf.len
We want to ensure that req->rq_private_buf.len is updated before req->rq_received, so that call_decode() doesn't use an old value for req->rq_rcv_buf.len. In 'call_decode()' itself, instead of using task->tk_status (which is set using req->rq_received) must use the actual value of req->rq_private_buf.len when deciding whether or not the received RPC reply is too short. Finally ensure that we set req->rq_rcv_buf.len to zero when retrying a request. A typo meant that we were resetting req->rq_private_buf.len in call_decode(), and then clobbering that value with the old rq_rcv_buf.len again in xprt_transmit(). Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 3ba64f9f84ba..5110a4ea7fdf 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -757,9 +757,10 @@ void xprt_complete_rqst(struct rpc_task *task, int copied)
task->tk_rtt = (long)jiffies - req->rq_xtime;
list_del_init(&req->rq_list);
+ req->rq_private_buf.len = copied;
/* Ensure all writes are done before we update req->rq_received */
smp_wmb();
- req->rq_received = req->rq_private_buf.len = copied;
+ req->rq_received = copied;
rpc_wake_up_queued_task(&xprt->pending, task);
}
EXPORT_SYMBOL_GPL(xprt_complete_rqst);