aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-09-24 12:00:27 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-10-01 18:22:11 -0400
commit8a19a0b6cb2e2216afd68ef2047f30260cc8a220 (patch)
treeae3c46e80fd5fcafc28c531d333b24e60de2e0e9
parent90051ea774613ffc6b8aad3dc665c8505d6205a8 (diff)
SUNRPC: Add RPC task and client level options to disable the resend timeout
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--include/linux/sunrpc/clnt.h2
-rw-r--r--include/linux/sunrpc/sched.h1
-rw-r--r--net/sunrpc/clnt.c5
-rw-r--r--net/sunrpc/xprt.c15
4 files changed, 19 insertions, 4 deletions
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 6740801aa71a..943ee895f2d1 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -49,6 +49,7 @@ struct rpc_clnt {
49 49
50 unsigned int cl_softrtry : 1,/* soft timeouts */ 50 unsigned int cl_softrtry : 1,/* soft timeouts */
51 cl_discrtry : 1,/* disconnect before retry */ 51 cl_discrtry : 1,/* disconnect before retry */
52 cl_noretranstimeo: 1,/* No retransmit timeouts */
52 cl_autobind : 1,/* use getport() */ 53 cl_autobind : 1,/* use getport() */
53 cl_chatty : 1;/* be verbose */ 54 cl_chatty : 1;/* be verbose */
54 55
@@ -126,6 +127,7 @@ struct rpc_create_args {
126#define RPC_CLNT_CREATE_QUIET (1UL << 6) 127#define RPC_CLNT_CREATE_QUIET (1UL << 6)
127#define RPC_CLNT_CREATE_INFINITE_SLOTS (1UL << 7) 128#define RPC_CLNT_CREATE_INFINITE_SLOTS (1UL << 7)
128#define RPC_CLNT_CREATE_NO_IDLE_TIMEOUT (1UL << 8) 129#define RPC_CLNT_CREATE_NO_IDLE_TIMEOUT (1UL << 8)
130#define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT (1UL << 9)
129 131
130struct rpc_clnt *rpc_create(struct rpc_create_args *args); 132struct rpc_clnt *rpc_create(struct rpc_create_args *args);
131struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *, 133struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 096ee58be11a..3a847de83fab 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -122,6 +122,7 @@ struct rpc_task_setup {
122#define RPC_TASK_SENT 0x0800 /* message was sent */ 122#define RPC_TASK_SENT 0x0800 /* message was sent */
123#define RPC_TASK_TIMEOUT 0x1000 /* fail with ETIMEDOUT on timeout */ 123#define RPC_TASK_TIMEOUT 0x1000 /* fail with ETIMEDOUT on timeout */
124#define RPC_TASK_NOCONNECT 0x2000 /* return ENOTCONN if not connected */ 124#define RPC_TASK_NOCONNECT 0x2000 /* return ENOTCONN if not connected */
125#define RPC_TASK_NO_RETRANS_TIMEOUT 0x4000 /* wait forever for a reply */
125 126
126#define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) 127#define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC)
127#define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) 128#define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index fa50e42aabd3..b58525009e40 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -772,6 +772,8 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
772 atomic_inc(&clnt->cl_count); 772 atomic_inc(&clnt->cl_count);
773 if (clnt->cl_softrtry) 773 if (clnt->cl_softrtry)
774 task->tk_flags |= RPC_TASK_SOFT; 774 task->tk_flags |= RPC_TASK_SOFT;
775 if (clnt->cl_noretranstimeo)
776 task->tk_flags |= RPC_TASK_NO_RETRANS_TIMEOUT;
775 if (sk_memalloc_socks()) { 777 if (sk_memalloc_socks()) {
776 struct rpc_xprt *xprt; 778 struct rpc_xprt *xprt;
777 779
@@ -1898,7 +1900,8 @@ call_status(struct rpc_task *task)
1898 rpc_delay(task, 3*HZ); 1900 rpc_delay(task, 3*HZ);
1899 case -ETIMEDOUT: 1901 case -ETIMEDOUT:
1900 task->tk_action = call_timeout; 1902 task->tk_action = call_timeout;
1901 if (task->tk_client->cl_discrtry) 1903 if (!(task->tk_flags & RPC_TASK_NO_RETRANS_TIMEOUT)
1904 && task->tk_client->cl_discrtry)
1902 xprt_conditional_disconnect(req->rq_xprt, 1905 xprt_conditional_disconnect(req->rq_xprt,
1903 req->rq_connect_cookie); 1906 req->rq_connect_cookie);
1904 break; 1907 break;
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 2326af57b9b9..d166d9947e36 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -873,9 +873,18 @@ bool xprt_prepare_transmit(struct rpc_task *task)
873 dprintk("RPC: %5u xprt_prepare_transmit\n", task->tk_pid); 873 dprintk("RPC: %5u xprt_prepare_transmit\n", task->tk_pid);
874 874
875 spin_lock_bh(&xprt->transport_lock); 875 spin_lock_bh(&xprt->transport_lock);
876 if (req->rq_reply_bytes_recvd && !req->rq_bytes_sent) { 876 if (!req->rq_bytes_sent) {
877 task->tk_status = req->rq_reply_bytes_recvd; 877 if (req->rq_reply_bytes_recvd) {
878 goto out_unlock; 878 task->tk_status = req->rq_reply_bytes_recvd;
879 goto out_unlock;
880 }
881 if ((task->tk_flags & RPC_TASK_NO_RETRANS_TIMEOUT)
882 && xprt_connected(xprt)
883 && req->rq_connect_cookie == xprt->connect_cookie) {
884 xprt->ops->set_retrans_timeout(task);
885 rpc_sleep_on(&xprt->pending, task, xprt_timer);
886 goto out_unlock;
887 }
879 } 888 }
880 if (!xprt->ops->reserve_xprt(xprt, task)) { 889 if (!xprt->ops->reserve_xprt(xprt, task)) {
881 task->tk_status = -EAGAIN; 890 task->tk_status = -EAGAIN;