aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2009-03-11 14:37:59 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-03-11 14:37:59 -0400
commitc8485e4d634f6df155040293928707f127f0d06d (patch)
tree72ec8a7ea829e4f7df4648e646353c55a037e50e /net/sunrpc/xprt.c
parent40d2549db5f515e415894def98b49db7d4c56714 (diff)
SUNRPC: Handle ECONNREFUSED correctly in xprt_transmit()
If we get an ECONNREFUSED error, we currently go to sleep on the 'xprt->sending' wait queue. The problem is that no timeout is set there, and there is nothing else that will wake the task up later. We should deal with ECONNREFUSED in call_status, given that is where we also deal with -EHOSTDOWN, and friends. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c38
1 files changed, 16 insertions, 22 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index d1afec640394..d588e755e107 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -901,32 +901,26 @@ void xprt_transmit(struct rpc_task *task)
901 req->rq_connect_cookie = xprt->connect_cookie; 901 req->rq_connect_cookie = xprt->connect_cookie;
902 req->rq_xtime = jiffies; 902 req->rq_xtime = jiffies;
903 status = xprt->ops->send_request(task); 903 status = xprt->ops->send_request(task);
904 if (status == 0) { 904 if (status != 0) {
905 dprintk("RPC: %5u xmit complete\n", task->tk_pid); 905 task->tk_status = status;
906 spin_lock_bh(&xprt->transport_lock); 906 return;
907 }
907 908
908 xprt->ops->set_retrans_timeout(task); 909 dprintk("RPC: %5u xmit complete\n", task->tk_pid);
910 spin_lock_bh(&xprt->transport_lock);
909 911
910 xprt->stat.sends++; 912 xprt->ops->set_retrans_timeout(task);
911 xprt->stat.req_u += xprt->stat.sends - xprt->stat.recvs;
912 xprt->stat.bklog_u += xprt->backlog.qlen;
913 913
914 /* Don't race with disconnect */ 914 xprt->stat.sends++;
915 if (!xprt_connected(xprt)) 915 xprt->stat.req_u += xprt->stat.sends - xprt->stat.recvs;
916 task->tk_status = -ENOTCONN; 916 xprt->stat.bklog_u += xprt->backlog.qlen;
917 else if (!req->rq_received)
918 rpc_sleep_on(&xprt->pending, task, xprt_timer);
919 spin_unlock_bh(&xprt->transport_lock);
920 return;
921 }
922 917
923 /* Note: at this point, task->tk_sleeping has not yet been set, 918 /* Don't race with disconnect */
924 * hence there is no danger of the waking up task being put on 919 if (!xprt_connected(xprt))
925 * schedq, and being picked up by a parallel run of rpciod(). 920 task->tk_status = -ENOTCONN;
926 */ 921 else if (!req->rq_received)
927 task->tk_status = status; 922 rpc_sleep_on(&xprt->pending, task, xprt_timer);
928 if (status == -ECONNREFUSED) 923 spin_unlock_bh(&xprt->transport_lock);
929 rpc_sleep_on(&xprt->sending, task, NULL);
930} 924}
931 925
932static inline void do_xprt_reserve(struct rpc_task *task) 926static inline void do_xprt_reserve(struct rpc_task *task)