aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2007-02-06 18:26:11 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-02-13 01:40:45 -0500
commit43d78ef2ba5bec26d0315859e8324bfc0be23766 (patch)
tree6ea576e0a20a11745c7a45b2a15dd855a45b655a /net
parenta301b777714087ea1d63dbec0173a13d416cd7a9 (diff)
NFS: disconnect before retrying NFSv4 requests over TCP
RFC3530 section 3.1.1 states an NFSv4 client MUST NOT send a request twice on the same connection unless it is the NULL procedure. Section 3.1.1 suggests that the client should disconnect and reconnect if it wants to retry a request. Implement this by adding an rpc_clnt flag that an ULP can use to specify that the underlying transport should be disconnected on a major timeout. The NFSv4 client asserts this new flag, and requests no retries after a minor retransmit timeout. Note that disconnecting on a retransmit is in general not safe to do if the RPC client does not reuse the TCP port number when reconnecting. See http://bugzilla.linux-nfs.org/show_bug.cgi?id=6 Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/clnt.c2
-rw-r--r--net/sunrpc/xprt.c10
2 files changed, 12 insertions, 0 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 393e70aee18..c21aa0a7f77 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -249,6 +249,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
249 clnt->cl_autobind = 1; 249 clnt->cl_autobind = 1;
250 if (args->flags & RPC_CLNT_CREATE_ONESHOT) 250 if (args->flags & RPC_CLNT_CREATE_ONESHOT)
251 clnt->cl_oneshot = 1; 251 clnt->cl_oneshot = 1;
252 if (args->flags & RPC_CLNT_CREATE_DISCRTRY)
253 clnt->cl_discrtry = 1;
252 254
253 return clnt; 255 return clnt;
254} 256}
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index cf59f7d315d..1975139b26e 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -735,6 +735,16 @@ void xprt_transmit(struct rpc_task *task)
735 xprt_reset_majortimeo(req); 735 xprt_reset_majortimeo(req);
736 /* Turn off autodisconnect */ 736 /* Turn off autodisconnect */
737 del_singleshot_timer_sync(&xprt->timer); 737 del_singleshot_timer_sync(&xprt->timer);
738 } else {
739 /* If all request bytes have been sent,
740 * then we must be retransmitting this one */
741 if (!req->rq_bytes_sent) {
742 if (task->tk_client->cl_discrtry) {
743 xprt_disconnect(xprt);
744 task->tk_status = -ENOTCONN;
745 return;
746 }
747 }
738 } 748 }
739 } else if (!req->rq_bytes_sent) 749 } else if (!req->rq_bytes_sent)
740 return; 750 return;