aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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 /fs
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 'fs')
-rw-r--r--fs/nfs/client.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index a3191f023490..c46e94fed9eb 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -394,7 +394,8 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
394static int nfs_create_rpc_client(struct nfs_client *clp, int proto, 394static int nfs_create_rpc_client(struct nfs_client *clp, int proto,
395 unsigned int timeo, 395 unsigned int timeo,
396 unsigned int retrans, 396 unsigned int retrans,
397 rpc_authflavor_t flavor) 397 rpc_authflavor_t flavor,
398 int flags)
398{ 399{
399 struct rpc_timeout timeparms; 400 struct rpc_timeout timeparms;
400 struct rpc_clnt *clnt = NULL; 401 struct rpc_clnt *clnt = NULL;
@@ -407,6 +408,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp, int proto,
407 .program = &nfs_program, 408 .program = &nfs_program,
408 .version = clp->rpc_ops->version, 409 .version = clp->rpc_ops->version,
409 .authflavor = flavor, 410 .authflavor = flavor,
411 .flags = flags,
410 }; 412 };
411 413
412 if (!IS_ERR(clp->cl_rpcclient)) 414 if (!IS_ERR(clp->cl_rpcclient))
@@ -548,7 +550,7 @@ static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *
548 * - RFC 2623, sec 2.3.2 550 * - RFC 2623, sec 2.3.2
549 */ 551 */
550 error = nfs_create_rpc_client(clp, proto, data->timeo, data->retrans, 552 error = nfs_create_rpc_client(clp, proto, data->timeo, data->retrans,
551 RPC_AUTH_UNIX); 553 RPC_AUTH_UNIX, 0);
552 if (error < 0) 554 if (error < 0)
553 goto error; 555 goto error;
554 nfs_mark_client_ready(clp, NFS_CS_READY); 556 nfs_mark_client_ready(clp, NFS_CS_READY);
@@ -868,7 +870,8 @@ static int nfs4_init_client(struct nfs_client *clp,
868 /* Check NFS protocol revision and initialize RPC op vector */ 870 /* Check NFS protocol revision and initialize RPC op vector */
869 clp->rpc_ops = &nfs_v4_clientops; 871 clp->rpc_ops = &nfs_v4_clientops;
870 872
871 error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour); 873 error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour,
874 RPC_CLNT_CREATE_DISCRTRY);
872 if (error < 0) 875 if (error < 0)
873 goto error; 876 goto error;
874 memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr)); 877 memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));