aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-03-23 16:10:00 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-03-27 12:24:36 -0400
commit0695314ef0920b745423510f1e96bf60415a404a (patch)
tree5a226e4308ff50a130f16c3365ba5e06d7ce6b5b /net
parent09a330f4b9324e40947cc4fff13606719382c580 (diff)
SUNRPC: Fix a regression when reconnecting
If the task needs to give up the socket lock in order to allow a reconnect to occur, then it must also clear the 'rq_bytes_sent' field so that when it retransmits, it knows to start from the beginning. Fixes: 718ba5b87343 ("SUNRPC: Add helpers to prevent socket create from racing") Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/xprt.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index e3015aede0d9..ed4aa786c240 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -326,6 +326,15 @@ out_unlock:
326 xprt_clear_locked(xprt); 326 xprt_clear_locked(xprt);
327} 327}
328 328
329static void xprt_task_clear_bytes_sent(struct rpc_task *task)
330{
331 if (task != NULL) {
332 struct rpc_rqst *req = task->tk_rqstp;
333 if (req != NULL)
334 req->rq_bytes_sent = 0;
335 }
336}
337
329/** 338/**
330 * xprt_release_xprt - allow other requests to use a transport 339 * xprt_release_xprt - allow other requests to use a transport
331 * @xprt: transport with other tasks potentially waiting 340 * @xprt: transport with other tasks potentially waiting
@@ -336,11 +345,7 @@ out_unlock:
336void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) 345void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
337{ 346{
338 if (xprt->snd_task == task) { 347 if (xprt->snd_task == task) {
339 if (task != NULL) { 348 xprt_task_clear_bytes_sent(task);
340 struct rpc_rqst *req = task->tk_rqstp;
341 if (req != NULL)
342 req->rq_bytes_sent = 0;
343 }
344 xprt_clear_locked(xprt); 349 xprt_clear_locked(xprt);
345 __xprt_lock_write_next(xprt); 350 __xprt_lock_write_next(xprt);
346 } 351 }
@@ -358,11 +363,7 @@ EXPORT_SYMBOL_GPL(xprt_release_xprt);
358void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task) 363void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
359{ 364{
360 if (xprt->snd_task == task) { 365 if (xprt->snd_task == task) {
361 if (task != NULL) { 366 xprt_task_clear_bytes_sent(task);
362 struct rpc_rqst *req = task->tk_rqstp;
363 if (req != NULL)
364 req->rq_bytes_sent = 0;
365 }
366 xprt_clear_locked(xprt); 367 xprt_clear_locked(xprt);
367 __xprt_lock_write_next_cong(xprt); 368 __xprt_lock_write_next_cong(xprt);
368 } 369 }
@@ -700,6 +701,7 @@ bool xprt_lock_connect(struct rpc_xprt *xprt,
700 goto out; 701 goto out;
701 if (xprt->snd_task != task) 702 if (xprt->snd_task != task)
702 goto out; 703 goto out;
704 xprt_task_clear_bytes_sent(task);
703 xprt->snd_task = cookie; 705 xprt->snd_task = cookie;
704 ret = true; 706 ret = true;
705out: 707out: