diff options
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 77e8800d4127..c458f8d1d6d1 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/udp.h> | 28 | #include <linux/udp.h> |
29 | #include <linux/tcp.h> | 29 | #include <linux/tcp.h> |
30 | #include <linux/sunrpc/clnt.h> | 30 | #include <linux/sunrpc/clnt.h> |
31 | #include <linux/sunrpc/sched.h> | ||
31 | #include <linux/file.h> | 32 | #include <linux/file.h> |
32 | 33 | ||
33 | #include <net/sock.h> | 34 | #include <net/sock.h> |
@@ -424,7 +425,7 @@ static void xs_close(struct rpc_xprt *xprt) | |||
424 | struct sock *sk = xprt->inet; | 425 | struct sock *sk = xprt->inet; |
425 | 426 | ||
426 | if (!sk) | 427 | if (!sk) |
427 | return; | 428 | goto clear_close_wait; |
428 | 429 | ||
429 | dprintk("RPC: xs_close xprt %p\n", xprt); | 430 | dprintk("RPC: xs_close xprt %p\n", xprt); |
430 | 431 | ||
@@ -441,6 +442,10 @@ static void xs_close(struct rpc_xprt *xprt) | |||
441 | sk->sk_no_check = 0; | 442 | sk->sk_no_check = 0; |
442 | 443 | ||
443 | sock_release(sock); | 444 | sock_release(sock); |
445 | clear_close_wait: | ||
446 | smp_mb__before_clear_bit(); | ||
447 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); | ||
448 | smp_mb__after_clear_bit(); | ||
444 | } | 449 | } |
445 | 450 | ||
446 | /** | 451 | /** |
@@ -800,9 +805,13 @@ static void xs_tcp_state_change(struct sock *sk) | |||
800 | case TCP_SYN_SENT: | 805 | case TCP_SYN_SENT: |
801 | case TCP_SYN_RECV: | 806 | case TCP_SYN_RECV: |
802 | break; | 807 | break; |
808 | case TCP_CLOSE_WAIT: | ||
809 | /* Try to schedule an autoclose RPC calls */ | ||
810 | set_bit(XPRT_CLOSE_WAIT, &xprt->state); | ||
811 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) | ||
812 | schedule_work(&xprt->task_cleanup); | ||
803 | default: | 813 | default: |
804 | xprt_disconnect(xprt); | 814 | xprt_disconnect(xprt); |
805 | break; | ||
806 | } | 815 | } |
807 | out: | 816 | out: |
808 | read_unlock(&sk->sk_callback_lock); | 817 | read_unlock(&sk->sk_callback_lock); |
@@ -920,6 +929,18 @@ static void xs_udp_timer(struct rpc_task *task) | |||
920 | xprt_adjust_cwnd(task, -ETIMEDOUT); | 929 | xprt_adjust_cwnd(task, -ETIMEDOUT); |
921 | } | 930 | } |
922 | 931 | ||
932 | /** | ||
933 | * xs_set_port - reset the port number in the remote endpoint address | ||
934 | * @xprt: generic transport | ||
935 | * @port: new port number | ||
936 | * | ||
937 | */ | ||
938 | static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) | ||
939 | { | ||
940 | dprintk("RPC: setting port for xprt %p to %u\n", xprt, port); | ||
941 | xprt->addr.sin_port = htons(port); | ||
942 | } | ||
943 | |||
923 | static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) | 944 | static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) |
924 | { | 945 | { |
925 | struct sockaddr_in myaddr = { | 946 | struct sockaddr_in myaddr = { |
@@ -1160,7 +1181,10 @@ static struct rpc_xprt_ops xs_udp_ops = { | |||
1160 | .set_buffer_size = xs_udp_set_buffer_size, | 1181 | .set_buffer_size = xs_udp_set_buffer_size, |
1161 | .reserve_xprt = xprt_reserve_xprt_cong, | 1182 | .reserve_xprt = xprt_reserve_xprt_cong, |
1162 | .release_xprt = xprt_release_xprt_cong, | 1183 | .release_xprt = xprt_release_xprt_cong, |
1184 | .set_port = xs_set_port, | ||
1163 | .connect = xs_connect, | 1185 | .connect = xs_connect, |
1186 | .buf_alloc = rpc_malloc, | ||
1187 | .buf_free = rpc_free, | ||
1164 | .send_request = xs_udp_send_request, | 1188 | .send_request = xs_udp_send_request, |
1165 | .set_retrans_timeout = xprt_set_retrans_timeout_rtt, | 1189 | .set_retrans_timeout = xprt_set_retrans_timeout_rtt, |
1166 | .timer = xs_udp_timer, | 1190 | .timer = xs_udp_timer, |
@@ -1172,7 +1196,10 @@ static struct rpc_xprt_ops xs_udp_ops = { | |||
1172 | static struct rpc_xprt_ops xs_tcp_ops = { | 1196 | static struct rpc_xprt_ops xs_tcp_ops = { |
1173 | .reserve_xprt = xprt_reserve_xprt, | 1197 | .reserve_xprt = xprt_reserve_xprt, |
1174 | .release_xprt = xprt_release_xprt, | 1198 | .release_xprt = xprt_release_xprt, |
1199 | .set_port = xs_set_port, | ||
1175 | .connect = xs_connect, | 1200 | .connect = xs_connect, |
1201 | .buf_alloc = rpc_malloc, | ||
1202 | .buf_free = rpc_free, | ||
1176 | .send_request = xs_tcp_send_request, | 1203 | .send_request = xs_tcp_send_request, |
1177 | .set_retrans_timeout = xprt_set_retrans_timeout_def, | 1204 | .set_retrans_timeout = xprt_set_retrans_timeout_def, |
1178 | .close = xs_close, | 1205 | .close = xs_close, |