aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2013-12-31 13:22:59 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2013-12-31 14:01:54 -0500
commit2118071d3b0d57a03fad77885f4fdc364798aa87 (patch)
treefe39bd6cceeccf9072518bff2a7f1f0d205371bd /net
parentdf2772700c6ee706be7b2fd16c6bf2c1bf63cda0 (diff)
SUNRPC: Report connection error values to rpc_tasks on the pending queue
Currently we only report EAGAIN, which is not descriptive enough for softconn tasks. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/xprtsock.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index dd9d295813cf..ab006b7b7ab8 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -257,6 +257,7 @@ struct sock_xprt {
257 void (*old_data_ready)(struct sock *, int); 257 void (*old_data_ready)(struct sock *, int);
258 void (*old_state_change)(struct sock *); 258 void (*old_state_change)(struct sock *);
259 void (*old_write_space)(struct sock *); 259 void (*old_write_space)(struct sock *);
260 void (*old_error_report)(struct sock *);
260}; 261};
261 262
262/* 263/*
@@ -274,6 +275,11 @@ struct sock_xprt {
274 */ 275 */
275#define TCP_RPC_REPLY (1UL << 6) 276#define TCP_RPC_REPLY (1UL << 6)
276 277
278static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
279{
280 return (struct rpc_xprt *) sk->sk_user_data;
281}
282
277static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt) 283static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt)
278{ 284{
279 return (struct sockaddr *) &xprt->addr; 285 return (struct sockaddr *) &xprt->addr;
@@ -799,6 +805,7 @@ static void xs_save_old_callbacks(struct sock_xprt *transport, struct sock *sk)
799 transport->old_data_ready = sk->sk_data_ready; 805 transport->old_data_ready = sk->sk_data_ready;
800 transport->old_state_change = sk->sk_state_change; 806 transport->old_state_change = sk->sk_state_change;
801 transport->old_write_space = sk->sk_write_space; 807 transport->old_write_space = sk->sk_write_space;
808 transport->old_error_report = sk->sk_error_report;
802} 809}
803 810
804static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk) 811static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk)
@@ -806,6 +813,33 @@ static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *s
806 sk->sk_data_ready = transport->old_data_ready; 813 sk->sk_data_ready = transport->old_data_ready;
807 sk->sk_state_change = transport->old_state_change; 814 sk->sk_state_change = transport->old_state_change;
808 sk->sk_write_space = transport->old_write_space; 815 sk->sk_write_space = transport->old_write_space;
816 sk->sk_error_report = transport->old_error_report;
817}
818
819/**
820 * xs_error_report - callback to handle TCP socket state errors
821 * @sk: socket
822 *
823 * Note: we don't call sock_error() since there may be a rpc_task
824 * using the socket, and so we don't want to clear sk->sk_err.
825 */
826static void xs_error_report(struct sock *sk)
827{
828 struct rpc_xprt *xprt;
829 int err;
830
831 read_lock_bh(&sk->sk_callback_lock);
832 if (!(xprt = xprt_from_sock(sk)))
833 goto out;
834
835 err = -sk->sk_err;
836 if (err == 0)
837 goto out;
838 dprintk("RPC: xs_error_report client %p, error=%d...\n",
839 xprt, -err);
840 xprt_wake_pending_tasks(xprt, err);
841 out:
842 read_unlock_bh(&sk->sk_callback_lock);
809} 843}
810 844
811static void xs_reset_transport(struct sock_xprt *transport) 845static void xs_reset_transport(struct sock_xprt *transport)
@@ -885,11 +919,6 @@ static void xs_destroy(struct rpc_xprt *xprt)
885 module_put(THIS_MODULE); 919 module_put(THIS_MODULE);
886} 920}
887 921
888static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
889{
890 return (struct rpc_xprt *) sk->sk_user_data;
891}
892
893static int xs_local_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb) 922static int xs_local_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
894{ 923{
895 struct xdr_skb_reader desc = { 924 struct xdr_skb_reader desc = {
@@ -1869,6 +1898,7 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,
1869 sk->sk_user_data = xprt; 1898 sk->sk_user_data = xprt;
1870 sk->sk_data_ready = xs_local_data_ready; 1899 sk->sk_data_ready = xs_local_data_ready;
1871 sk->sk_write_space = xs_udp_write_space; 1900 sk->sk_write_space = xs_udp_write_space;
1901 sk->sk_error_report = xs_error_report;
1872 sk->sk_allocation = GFP_ATOMIC; 1902 sk->sk_allocation = GFP_ATOMIC;
1873 1903
1874 xprt_clear_connected(xprt); 1904 xprt_clear_connected(xprt);
@@ -2146,6 +2176,7 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
2146 sk->sk_data_ready = xs_tcp_data_ready; 2176 sk->sk_data_ready = xs_tcp_data_ready;
2147 sk->sk_state_change = xs_tcp_state_change; 2177 sk->sk_state_change = xs_tcp_state_change;
2148 sk->sk_write_space = xs_tcp_write_space; 2178 sk->sk_write_space = xs_tcp_write_space;
2179 sk->sk_error_report = xs_error_report;
2149 sk->sk_allocation = GFP_ATOMIC; 2180 sk->sk_allocation = GFP_ATOMIC;
2150 2181
2151 /* socket options */ 2182 /* socket options */