aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sunrpc/clnt.c15
-rw-r--r--net/sunrpc/xprt.c20
-rw-r--r--net/sunrpc/xprtsock.c58
3 files changed, 41 insertions, 52 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 145715b5311..5abab094441 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1032,27 +1032,20 @@ call_connect_status(struct rpc_task *task)
1032 dprint_status(task); 1032 dprint_status(task);
1033 1033
1034 task->tk_status = 0; 1034 task->tk_status = 0;
1035 if (status >= 0) { 1035 if (status >= 0 || status == -EAGAIN) {
1036 clnt->cl_stats->netreconn++; 1036 clnt->cl_stats->netreconn++;
1037 task->tk_action = call_transmit; 1037 task->tk_action = call_transmit;
1038 return; 1038 return;
1039 } 1039 }
1040 1040
1041 /* Something failed: remote service port may have changed */
1042 rpc_force_rebind(clnt);
1043
1044 switch (status) { 1041 switch (status) {
1045 case -ENOTCONN:
1046 case -EAGAIN:
1047 task->tk_action = call_bind;
1048 if (!RPC_IS_SOFT(task))
1049 return;
1050 /* if soft mounted, test if we've timed out */ 1042 /* if soft mounted, test if we've timed out */
1051 case -ETIMEDOUT: 1043 case -ETIMEDOUT:
1052 task->tk_action = call_timeout; 1044 task->tk_action = call_timeout;
1053 return; 1045 break;
1046 default:
1047 rpc_exit(task, -EIO);
1054 } 1048 }
1055 rpc_exit(task, -EIO);
1056} 1049}
1057 1050
1058/* 1051/*
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index d588e755e10..a0bfe53f162 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -611,7 +611,7 @@ void xprt_disconnect_done(struct rpc_xprt *xprt)
611 dprintk("RPC: disconnected transport %p\n", xprt); 611 dprintk("RPC: disconnected transport %p\n", xprt);
612 spin_lock_bh(&xprt->transport_lock); 612 spin_lock_bh(&xprt->transport_lock);
613 xprt_clear_connected(xprt); 613 xprt_clear_connected(xprt);
614 xprt_wake_pending_tasks(xprt, -ENOTCONN); 614 xprt_wake_pending_tasks(xprt, -EAGAIN);
615 spin_unlock_bh(&xprt->transport_lock); 615 spin_unlock_bh(&xprt->transport_lock);
616} 616}
617EXPORT_SYMBOL_GPL(xprt_disconnect_done); 617EXPORT_SYMBOL_GPL(xprt_disconnect_done);
@@ -629,7 +629,7 @@ void xprt_force_disconnect(struct rpc_xprt *xprt)
629 /* Try to schedule an autoclose RPC call */ 629 /* Try to schedule an autoclose RPC call */
630 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) 630 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
631 queue_work(rpciod_workqueue, &xprt->task_cleanup); 631 queue_work(rpciod_workqueue, &xprt->task_cleanup);
632 xprt_wake_pending_tasks(xprt, -ENOTCONN); 632 xprt_wake_pending_tasks(xprt, -EAGAIN);
633 spin_unlock_bh(&xprt->transport_lock); 633 spin_unlock_bh(&xprt->transport_lock);
634} 634}
635 635
@@ -656,7 +656,7 @@ void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie)
656 /* Try to schedule an autoclose RPC call */ 656 /* Try to schedule an autoclose RPC call */
657 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) 657 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
658 queue_work(rpciod_workqueue, &xprt->task_cleanup); 658 queue_work(rpciod_workqueue, &xprt->task_cleanup);
659 xprt_wake_pending_tasks(xprt, -ENOTCONN); 659 xprt_wake_pending_tasks(xprt, -EAGAIN);
660out: 660out:
661 spin_unlock_bh(&xprt->transport_lock); 661 spin_unlock_bh(&xprt->transport_lock);
662} 662}
@@ -726,9 +726,8 @@ static void xprt_connect_status(struct rpc_task *task)
726 } 726 }
727 727
728 switch (task->tk_status) { 728 switch (task->tk_status) {
729 case -ENOTCONN: 729 case -EAGAIN:
730 dprintk("RPC: %5u xprt_connect_status: connection broken\n", 730 dprintk("RPC: %5u xprt_connect_status: retrying\n", task->tk_pid);
731 task->tk_pid);
732 break; 731 break;
733 case -ETIMEDOUT: 732 case -ETIMEDOUT:
734 dprintk("RPC: %5u xprt_connect_status: connect attempt timed " 733 dprintk("RPC: %5u xprt_connect_status: connect attempt timed "
@@ -849,15 +848,8 @@ int xprt_prepare_transmit(struct rpc_task *task)
849 err = req->rq_received; 848 err = req->rq_received;
850 goto out_unlock; 849 goto out_unlock;
851 } 850 }
852 if (!xprt->ops->reserve_xprt(task)) { 851 if (!xprt->ops->reserve_xprt(task))
853 err = -EAGAIN; 852 err = -EAGAIN;
854 goto out_unlock;
855 }
856
857 if (!xprt_connected(xprt)) {
858 err = -ENOTCONN;
859 goto out_unlock;
860 }
861out_unlock: 853out_unlock:
862 spin_unlock_bh(&xprt->transport_lock); 854 spin_unlock_bh(&xprt->transport_lock);
863 return err; 855 return err;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 879af6f27b4..8e58b0b5460 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1162,7 +1162,7 @@ static void xs_tcp_state_change(struct sock *sk)
1162 transport->tcp_flags = 1162 transport->tcp_flags =
1163 TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID; 1163 TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID;
1164 1164
1165 xprt_wake_pending_tasks(xprt, 0); 1165 xprt_wake_pending_tasks(xprt, -EAGAIN);
1166 } 1166 }
1167 spin_unlock_bh(&xprt->transport_lock); 1167 spin_unlock_bh(&xprt->transport_lock);
1168 break; 1168 break;
@@ -1721,20 +1721,22 @@ static void xs_tcp_connect_worker4(struct work_struct *work)
1721 dprintk("RPC: %p connect status %d connected %d sock state %d\n", 1721 dprintk("RPC: %p connect status %d connected %d sock state %d\n",
1722 xprt, -status, xprt_connected(xprt), 1722 xprt, -status, xprt_connected(xprt),
1723 sock->sk->sk_state); 1723 sock->sk->sk_state);
1724 if (status < 0) { 1724 switch (status) {
1725 switch (status) { 1725 case 0:
1726 case -EINPROGRESS: 1726 case -EINPROGRESS:
1727 case -EALREADY: 1727 case -EALREADY:
1728 goto out_clear; 1728 goto out_clear;
1729 case -ECONNREFUSED: 1729 case -ECONNREFUSED:
1730 case -ECONNRESET: 1730 case -ECONNRESET:
1731 /* retry with existing socket, after a delay */ 1731 /* retry with existing socket, after a delay */
1732 break; 1732 break;
1733 default: 1733 default:
1734 /* get rid of existing socket, and retry */ 1734 /* get rid of existing socket, and retry */
1735 xs_tcp_shutdown(xprt); 1735 xs_tcp_shutdown(xprt);
1736 } 1736 printk("%s: connect returned unhandled error %d\n",
1737 __func__, status);
1737 } 1738 }
1739 status = -EAGAIN;
1738out: 1740out:
1739 xprt_wake_pending_tasks(xprt, status); 1741 xprt_wake_pending_tasks(xprt, status);
1740out_clear: 1742out_clear:
@@ -1780,20 +1782,22 @@ static void xs_tcp_connect_worker6(struct work_struct *work)
1780 status = xs_tcp_finish_connecting(xprt, sock); 1782 status = xs_tcp_finish_connecting(xprt, sock);
1781 dprintk("RPC: %p connect status %d connected %d sock state %d\n", 1783 dprintk("RPC: %p connect status %d connected %d sock state %d\n",
1782 xprt, -status, xprt_connected(xprt), sock->sk->sk_state); 1784 xprt, -status, xprt_connected(xprt), sock->sk->sk_state);
1783 if (status < 0) { 1785 switch (status) {
1784 switch (status) { 1786 case 0:
1785 case -EINPROGRESS: 1787 case -EINPROGRESS:
1786 case -EALREADY: 1788 case -EALREADY:
1787 goto out_clear; 1789 goto out_clear;
1788 case -ECONNREFUSED: 1790 case -ECONNREFUSED:
1789 case -ECONNRESET: 1791 case -ECONNRESET:
1790 /* retry with existing socket, after a delay */ 1792 /* retry with existing socket, after a delay */
1791 break; 1793 break;
1792 default: 1794 default:
1793 /* get rid of existing socket, and retry */ 1795 /* get rid of existing socket, and retry */
1794 xs_tcp_shutdown(xprt); 1796 xs_tcp_shutdown(xprt);
1795 } 1797 printk("%s: connect returned unhandled error %d\n",
1798 __func__, status);
1796 } 1799 }
1800 status = -EAGAIN;
1797out: 1801out:
1798 xprt_wake_pending_tasks(xprt, status); 1802 xprt_wake_pending_tasks(xprt, status);
1799out_clear: 1803out_clear: