aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprtsock.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r--net/sunrpc/xprtsock.c58
1 files changed, 48 insertions, 10 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index f9ce3c9949d5..82a9b6286dd3 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -249,6 +249,7 @@ struct sock_xprt {
249 void (*old_data_ready)(struct sock *, int); 249 void (*old_data_ready)(struct sock *, int);
250 void (*old_state_change)(struct sock *); 250 void (*old_state_change)(struct sock *);
251 void (*old_write_space)(struct sock *); 251 void (*old_write_space)(struct sock *);
252 void (*old_error_report)(struct sock *);
252}; 253};
253 254
254/* 255/*
@@ -696,8 +697,9 @@ static int xs_tcp_send_request(struct rpc_task *task)
696 case -EAGAIN: 697 case -EAGAIN:
697 xs_nospace(task); 698 xs_nospace(task);
698 break; 699 break;
699 case -ECONNREFUSED:
700 case -ECONNRESET: 700 case -ECONNRESET:
701 xs_tcp_shutdown(xprt);
702 case -ECONNREFUSED:
701 case -ENOTCONN: 703 case -ENOTCONN:
702 case -EPIPE: 704 case -EPIPE:
703 status = -ENOTCONN; 705 status = -ENOTCONN;
@@ -740,6 +742,22 @@ out_release:
740 xprt_release_xprt(xprt, task); 742 xprt_release_xprt(xprt, task);
741} 743}
742 744
745static void xs_save_old_callbacks(struct sock_xprt *transport, struct sock *sk)
746{
747 transport->old_data_ready = sk->sk_data_ready;
748 transport->old_state_change = sk->sk_state_change;
749 transport->old_write_space = sk->sk_write_space;
750 transport->old_error_report = sk->sk_error_report;
751}
752
753static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk)
754{
755 sk->sk_data_ready = transport->old_data_ready;
756 sk->sk_state_change = transport->old_state_change;
757 sk->sk_write_space = transport->old_write_space;
758 sk->sk_error_report = transport->old_error_report;
759}
760
743/** 761/**
744 * xs_close - close a socket 762 * xs_close - close a socket
745 * @xprt: transport 763 * @xprt: transport
@@ -763,9 +781,8 @@ static void xs_close(struct rpc_xprt *xprt)
763 transport->sock = NULL; 781 transport->sock = NULL;
764 782
765 sk->sk_user_data = NULL; 783 sk->sk_user_data = NULL;
766 sk->sk_data_ready = transport->old_data_ready; 784
767 sk->sk_state_change = transport->old_state_change; 785 xs_restore_old_callbacks(transport, sk);
768 sk->sk_write_space = transport->old_write_space;
769 write_unlock_bh(&sk->sk_callback_lock); 786 write_unlock_bh(&sk->sk_callback_lock);
770 787
771 sk->sk_no_check = 0; 788 sk->sk_no_check = 0;
@@ -1178,6 +1195,28 @@ static void xs_tcp_state_change(struct sock *sk)
1178} 1195}
1179 1196
1180/** 1197/**
1198 * xs_tcp_error_report - callback mainly for catching RST events
1199 * @sk: socket
1200 */
1201static void xs_tcp_error_report(struct sock *sk)
1202{
1203 struct rpc_xprt *xprt;
1204
1205 read_lock(&sk->sk_callback_lock);
1206 if (sk->sk_err != ECONNRESET || sk->sk_state != TCP_ESTABLISHED)
1207 goto out;
1208 if (!(xprt = xprt_from_sock(sk)))
1209 goto out;
1210 dprintk("RPC: %s client %p...\n"
1211 "RPC: error %d\n",
1212 __func__, xprt, sk->sk_err);
1213
1214 xprt_force_disconnect(xprt);
1215out:
1216 read_unlock(&sk->sk_callback_lock);
1217}
1218
1219/**
1181 * xs_udp_write_space - callback invoked when socket buffer space 1220 * xs_udp_write_space - callback invoked when socket buffer space
1182 * becomes available 1221 * becomes available
1183 * @sk: socket whose state has changed 1222 * @sk: socket whose state has changed
@@ -1452,10 +1491,9 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
1452 1491
1453 write_lock_bh(&sk->sk_callback_lock); 1492 write_lock_bh(&sk->sk_callback_lock);
1454 1493
1494 xs_save_old_callbacks(transport, sk);
1495
1455 sk->sk_user_data = xprt; 1496 sk->sk_user_data = xprt;
1456 transport->old_data_ready = sk->sk_data_ready;
1457 transport->old_state_change = sk->sk_state_change;
1458 transport->old_write_space = sk->sk_write_space;
1459 sk->sk_data_ready = xs_udp_data_ready; 1497 sk->sk_data_ready = xs_udp_data_ready;
1460 sk->sk_write_space = xs_udp_write_space; 1498 sk->sk_write_space = xs_udp_write_space;
1461 sk->sk_no_check = UDP_CSUM_NORCV; 1499 sk->sk_no_check = UDP_CSUM_NORCV;
@@ -1587,13 +1625,13 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
1587 1625
1588 write_lock_bh(&sk->sk_callback_lock); 1626 write_lock_bh(&sk->sk_callback_lock);
1589 1627
1628 xs_save_old_callbacks(transport, sk);
1629
1590 sk->sk_user_data = xprt; 1630 sk->sk_user_data = xprt;
1591 transport->old_data_ready = sk->sk_data_ready;
1592 transport->old_state_change = sk->sk_state_change;
1593 transport->old_write_space = sk->sk_write_space;
1594 sk->sk_data_ready = xs_tcp_data_ready; 1631 sk->sk_data_ready = xs_tcp_data_ready;
1595 sk->sk_state_change = xs_tcp_state_change; 1632 sk->sk_state_change = xs_tcp_state_change;
1596 sk->sk_write_space = xs_tcp_write_space; 1633 sk->sk_write_space = xs_tcp_write_space;
1634 sk->sk_error_report = xs_tcp_error_report;
1597 sk->sk_allocation = GFP_ATOMIC; 1635 sk->sk_allocation = GFP_ATOMIC;
1598 1636
1599 /* socket options */ 1637 /* socket options */