diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/clnt.c | 15 | ||||
-rw-r--r-- | net/sunrpc/xprt.c | 20 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 58 |
3 files changed, 41 insertions, 52 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 145715b53115..5abab094441f 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 d588e755e107..a0bfe53f1621 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 | } |
617 | EXPORT_SYMBOL_GPL(xprt_disconnect_done); | 617 | EXPORT_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); |
660 | out: | 660 | out: |
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 | } | ||
861 | out_unlock: | 853 | out_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 879af6f27b4c..8e58b0b5460b 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; | ||
1738 | out: | 1740 | out: |
1739 | xprt_wake_pending_tasks(xprt, status); | 1741 | xprt_wake_pending_tasks(xprt, status); |
1740 | out_clear: | 1742 | out_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; | ||
1797 | out: | 1801 | out: |
1798 | xprt_wake_pending_tasks(xprt, status); | 1802 | xprt_wake_pending_tasks(xprt, status); |
1799 | out_clear: | 1803 | out_clear: |