From: Chuck Lever <chuck.lever@oracle.com>
To: trond.myklebust@fys.uio.no
Cc: nfs@lists.sourceforge.net
Subject: [PATCH 06/15] NFS: disconnect before retrying NFSv4 requests over TCP
Date: Wed, 24 Jan 2007 14:19:57 -0500 [thread overview]
Message-ID: <20070124191957.31133.48291.stgit@localhost.localdomain> (raw)
In-Reply-To: <20070124191704.31133.12713.stgit@localhost.localdomain>
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>
---
fs/nfs/client.c | 9 ++++++---
include/linux/sunrpc/clnt.h | 2 ++
net/sunrpc/clnt.c | 2 ++
net/sunrpc/xprt.c | 10 ++++++++++
4 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 23ab145..a514599 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -394,7 +394,8 @@ static void nfs_init_timeout_values(stru
static int nfs_create_rpc_client(struct nfs_client *clp, int proto,
unsigned int timeo,
unsigned int retrans,
- rpc_authflavor_t flavor)
+ rpc_authflavor_t flavor,
+ int flags)
{
struct rpc_timeout timeparms;
struct rpc_clnt *clnt = NULL;
@@ -407,6 +408,7 @@ static int nfs_create_rpc_client(struct
.program = &nfs_program,
.version = clp->rpc_ops->version,
.authflavor = flavor,
+ .flags = flags,
};
if (!IS_ERR(clp->cl_rpcclient))
@@ -548,7 +550,7 @@ #endif
* - RFC 2623, sec 2.3.2
*/
error = nfs_create_rpc_client(clp, proto, data->timeo, data->retrans,
- RPC_AUTH_UNIX);
+ RPC_AUTH_UNIX, 0);
if (error < 0)
goto error;
nfs_mark_client_ready(clp, NFS_CS_READY);
@@ -868,7 +870,8 @@ static int nfs4_init_client(struct nfs_c
/* Check NFS protocol revision and initialize RPC op vector */
clp->rpc_ops = &nfs_v4_clientops;
- error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour);
+ error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour,
+ RPC_CLNT_CREATE_DISCRTRY);
if (error < 0)
goto error;
memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index a1be89d..c7a78ee 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -40,6 +40,7 @@ struct rpc_clnt {
unsigned int cl_softrtry : 1,/* soft timeouts */
cl_intr : 1,/* interruptible */
+ cl_discrtry : 1,/* disconnect before retry */
cl_autobind : 1,/* use getport() */
cl_oneshot : 1,/* dispose after use */
cl_dead : 1;/* abandoned */
@@ -111,6 +112,7 @@ #define RPC_CLNT_CREATE_AUTOBIND (1UL <<
#define RPC_CLNT_CREATE_ONESHOT (1UL << 3)
#define RPC_CLNT_CREATE_NONPRIVPORT (1UL << 4)
#define RPC_CLNT_CREATE_NOPING (1UL << 5)
+#define RPC_CLNT_CREATE_DISCRTRY (1UL << 6)
struct rpc_clnt *rpc_create(struct rpc_create_args *args);
struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 244cce4..a5ce924 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -249,6 +249,8 @@ struct rpc_clnt *rpc_create(struct rpc_c
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 9f787ac..815addd 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;
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
next prev parent reply other threads:[~2007-01-24 19:21 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-24 19:17 [PATCH 00/15] patches for 2.6.21 Chuck Lever
2007-01-24 19:19 ` [PATCH 01/15] NFS: fix print format for tk_pid Chuck Lever
2007-01-24 19:19 ` [PATCH 02/15] SUNRPC: fix print format for tk_pid in auth_gss support Chuck Lever
2007-01-24 19:19 ` [PATCH 03/15] SUNRPC: fix print format for tk_pid Chuck Lever
2007-01-24 19:19 ` [PATCH 04/15] SUNRPC: Eliminate side effects from rpc_malloc Chuck Lever
2007-01-24 19:19 ` [PATCH 05/15] SUNRPC: Make rpc_free API more generic Chuck Lever
2007-01-24 19:19 ` Chuck Lever [this message]
2007-01-24 19:20 ` [PATCH 07/15] SUNRPC: introduce rpcbind: replacement for in-kernel portmapper Chuck Lever
2007-01-24 19:20 ` [PATCH 08/15] SUNRPC: switch socket-based RPC transports to use rpcbind Chuck Lever
2007-01-24 19:20 ` [PATCH 09/15] SUNRPC: switch the RPC server to use the new rpcbind registration API Chuck Lever
2007-01-24 19:20 ` [PATCH 10/15] NFS: switch NFSROOT to use new rpcbind client Chuck Lever
2007-01-24 19:20 ` [PATCH 11/15] SUNRPC: remove old portmapper Chuck Lever
2007-01-24 19:20 ` [PATCH 12/15] SUNRPC: RPC client should retry with different versions of rpcbind Chuck Lever
2007-01-24 19:20 ` [PATCH 13/15] SUNRPC: RPC buffer size estimates are too large Chuck Lever
2007-01-24 20:37 ` J. Bruce Fields
2007-01-24 20:41 ` Chuck Lever
2007-01-24 20:51 ` J. Bruce Fields
2007-01-24 21:09 ` Chuck Lever
2007-01-24 21:25 ` J. Bruce Fields
2007-01-24 21:28 ` Chuck Lever
2007-01-24 20:47 ` J. Bruce Fields
2007-01-24 20:50 ` Chuck Lever
2007-01-24 21:01 ` J. Bruce Fields
2007-01-24 21:11 ` Chuck Lever
2007-01-24 19:20 ` [PATCH 14/15] NLM: Shrink the maximum request size of NLM4 requests Chuck Lever
2007-01-24 19:20 ` [PATCH 15/15] SUNRPC: Debugging aid Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070124191957.31133.48291.stgit@localhost.localdomain \
--to=chuck.lever@oracle.com \
--cc=nfs@lists.sourceforge.net \
--cc=trond.myklebust@fys.uio.no \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox