From 43d78ef2ba5bec26d0315859e8324bfc0be23766 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 6 Feb 2007 18:26:11 -0500 Subject: 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 Signed-off-by: Trond Myklebust --- net/sunrpc/clnt.c | 2 ++ net/sunrpc/xprt.c | 10 ++++++++++ 2 files changed, 12 insertions(+) (limited to 'net/sunrpc') diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 393e70aee181..c21aa0a7f770 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) clnt->cl_autobind = 1; if (args->flags & RPC_CLNT_CREATE_ONESHOT) clnt->cl_oneshot = 1; + if (args->flags & RPC_CLNT_CREATE_DISCRTRY) + clnt->cl_discrtry = 1; return clnt; } diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index cf59f7d315d0..1975139b26e7 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -735,6 +735,16 @@ void xprt_transmit(struct rpc_task *task) xprt_reset_majortimeo(req); /* Turn off autodisconnect */ del_singleshot_timer_sync(&xprt->timer); + } else { + /* If all request bytes have been sent, + * then we must be retransmitting this one */ + if (!req->rq_bytes_sent) { + if (task->tk_client->cl_discrtry) { + xprt_disconnect(xprt); + task->tk_status = -ENOTCONN; + return; + } + } } } else if (!req->rq_bytes_sent) return; -- cgit v1.2.3-59-g8ed1b