Browse Source

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>
Trond Myklebust 10 years ago
parent
commit
0695314ef0
1 changed files with 12 additions and 10 deletions
  1. 12 10
      net/sunrpc/xprt.c

+ 12 - 10
net/sunrpc/xprt.c

@@ -326,6 +326,15 @@ out_unlock:
 	xprt_clear_locked(xprt);
 	xprt_clear_locked(xprt);
 }
 }
 
 
+static void xprt_task_clear_bytes_sent(struct rpc_task *task)
+{
+	if (task != NULL) {
+		struct rpc_rqst *req = task->tk_rqstp;
+		if (req != NULL)
+			req->rq_bytes_sent = 0;
+	}
+}
+
 /**
 /**
  * xprt_release_xprt - allow other requests to use a transport
  * xprt_release_xprt - allow other requests to use a transport
  * @xprt: transport with other tasks potentially waiting
  * @xprt: transport with other tasks potentially waiting
@@ -336,11 +345,7 @@ out_unlock:
 void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
 void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
 {
 {
 	if (xprt->snd_task == task) {
 	if (xprt->snd_task == task) {
-		if (task != NULL) {
-			struct rpc_rqst *req = task->tk_rqstp;
-			if (req != NULL)
-				req->rq_bytes_sent = 0;
-		}
+		xprt_task_clear_bytes_sent(task);
 		xprt_clear_locked(xprt);
 		xprt_clear_locked(xprt);
 		__xprt_lock_write_next(xprt);
 		__xprt_lock_write_next(xprt);
 	}
 	}
@@ -358,11 +363,7 @@ EXPORT_SYMBOL_GPL(xprt_release_xprt);
 void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
 void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
 {
 {
 	if (xprt->snd_task == task) {
 	if (xprt->snd_task == task) {
-		if (task != NULL) {
-			struct rpc_rqst *req = task->tk_rqstp;
-			if (req != NULL)
-				req->rq_bytes_sent = 0;
-		}
+		xprt_task_clear_bytes_sent(task);
 		xprt_clear_locked(xprt);
 		xprt_clear_locked(xprt);
 		__xprt_lock_write_next_cong(xprt);
 		__xprt_lock_write_next_cong(xprt);
 	}
 	}
@@ -700,6 +701,7 @@ bool xprt_lock_connect(struct rpc_xprt *xprt,
 		goto out;
 		goto out;
 	if (xprt->snd_task != task)
 	if (xprt->snd_task != task)
 		goto out;
 		goto out;
+	xprt_task_clear_bytes_sent(task);
 	xprt->snd_task = cookie;
 	xprt->snd_task = cookie;
 	ret = true;
 	ret = true;
 out:
 out: