diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-08-05 19:03:31 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-08-05 19:22:22 -0400 |
commit | 8d480326c3d6921ff5f1cc988c993bd572248deb (patch) | |
tree | eb2eac08a44bc78241d78291de545f37f6f3fd51 | |
parent | fb10fb67ad2ce43d5e5b8ad22d2ba826844acc56 (diff) |
NFSv4: Cap the transport reconnection timer at 1/2 lease period
We don't want to miss a lease period renewal due to the TCP connection
failing to reconnect in a timely fashion. To ensure this doesn't happen,
cap the reconnection timer so that we retry the connection attempt
at least every 1/2 lease period.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r-- | fs/nfs/nfs4renewd.c | 3 | ||||
-rw-r--r-- | include/linux/sunrpc/clnt.h | 2 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 21 |
3 files changed, 26 insertions, 0 deletions
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index 062029ab344a..82e77198d17e 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c | |||
@@ -151,6 +151,9 @@ void nfs4_set_lease_period(struct nfs_client *clp, | |||
151 | clp->cl_lease_time = lease; | 151 | clp->cl_lease_time = lease; |
152 | clp->cl_last_renewal = lastrenewed; | 152 | clp->cl_last_renewal = lastrenewed; |
153 | spin_unlock(&clp->cl_lock); | 153 | spin_unlock(&clp->cl_lock); |
154 | |||
155 | /* Cap maximum reconnect timeout at 1/2 lease period */ | ||
156 | rpc_cap_max_reconnect_timeout(clp->cl_rpcclient, lease >> 1); | ||
154 | } | 157 | } |
155 | 158 | ||
156 | /* | 159 | /* |
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index b6810c92b8bb..5c02b0691587 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h | |||
@@ -195,6 +195,8 @@ int rpc_clnt_add_xprt(struct rpc_clnt *, struct xprt_create *, | |||
195 | struct rpc_xprt *, | 195 | struct rpc_xprt *, |
196 | void *), | 196 | void *), |
197 | void *data); | 197 | void *data); |
198 | void rpc_cap_max_reconnect_timeout(struct rpc_clnt *clnt, | ||
199 | unsigned long timeo); | ||
198 | 200 | ||
199 | const char *rpc_proc_name(const struct rpc_task *task); | 201 | const char *rpc_proc_name(const struct rpc_task *task); |
200 | #endif /* __KERNEL__ */ | 202 | #endif /* __KERNEL__ */ |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index faac5472d14d..7f79fb7dc6a0 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -2676,6 +2676,27 @@ out_put_switch: | |||
2676 | } | 2676 | } |
2677 | EXPORT_SYMBOL_GPL(rpc_clnt_add_xprt); | 2677 | EXPORT_SYMBOL_GPL(rpc_clnt_add_xprt); |
2678 | 2678 | ||
2679 | static int | ||
2680 | rpc_xprt_cap_max_reconnect_timeout(struct rpc_clnt *clnt, | ||
2681 | struct rpc_xprt *xprt, | ||
2682 | void *data) | ||
2683 | { | ||
2684 | unsigned long timeout = *((unsigned long *)data); | ||
2685 | |||
2686 | if (timeout < xprt->max_reconnect_timeout) | ||
2687 | xprt->max_reconnect_timeout = timeout; | ||
2688 | return 0; | ||
2689 | } | ||
2690 | |||
2691 | void | ||
2692 | rpc_cap_max_reconnect_timeout(struct rpc_clnt *clnt, unsigned long timeo) | ||
2693 | { | ||
2694 | rpc_clnt_iterate_for_each_xprt(clnt, | ||
2695 | rpc_xprt_cap_max_reconnect_timeout, | ||
2696 | &timeo); | ||
2697 | } | ||
2698 | EXPORT_SYMBOL_GPL(rpc_cap_max_reconnect_timeout); | ||
2699 | |||
2679 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | 2700 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
2680 | static void rpc_show_header(void) | 2701 | static void rpc_show_header(void) |
2681 | { | 2702 | { |