diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-12-23 16:30:11 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-01-06 11:53:57 -0500 |
commit | 69b6ba3712b796a66595cfaf0a5ab4dfe1cf964a (patch) | |
tree | e75274a8f4b12e086bf3481b98f97a6b5abda00f | |
parent | 262a09823bb07c6aafb6c1d312cde613d0b90c85 (diff) |
SUNRPC: Ensure the server closes sockets in a timely fashion
We want to ensure that connected sockets close down the connection when we
set XPT_CLOSE, so that we don't keep it hanging while cleaning up all the
stuff that is keeping a reference to the socket.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
-rw-r--r-- | net/sunrpc/svcsock.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index ef3238d665ee..cccfa7deb9af 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -59,6 +59,7 @@ static void svc_udp_data_ready(struct sock *, int); | |||
59 | static int svc_udp_recvfrom(struct svc_rqst *); | 59 | static int svc_udp_recvfrom(struct svc_rqst *); |
60 | static int svc_udp_sendto(struct svc_rqst *); | 60 | static int svc_udp_sendto(struct svc_rqst *); |
61 | static void svc_sock_detach(struct svc_xprt *); | 61 | static void svc_sock_detach(struct svc_xprt *); |
62 | static void svc_tcp_sock_detach(struct svc_xprt *); | ||
62 | static void svc_sock_free(struct svc_xprt *); | 63 | static void svc_sock_free(struct svc_xprt *); |
63 | 64 | ||
64 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, | 65 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, |
@@ -1017,7 +1018,7 @@ static struct svc_xprt_ops svc_tcp_ops = { | |||
1017 | .xpo_recvfrom = svc_tcp_recvfrom, | 1018 | .xpo_recvfrom = svc_tcp_recvfrom, |
1018 | .xpo_sendto = svc_tcp_sendto, | 1019 | .xpo_sendto = svc_tcp_sendto, |
1019 | .xpo_release_rqst = svc_release_skb, | 1020 | .xpo_release_rqst = svc_release_skb, |
1020 | .xpo_detach = svc_sock_detach, | 1021 | .xpo_detach = svc_tcp_sock_detach, |
1021 | .xpo_free = svc_sock_free, | 1022 | .xpo_free = svc_sock_free, |
1022 | .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr, | 1023 | .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr, |
1023 | .xpo_has_wspace = svc_tcp_has_wspace, | 1024 | .xpo_has_wspace = svc_tcp_has_wspace, |
@@ -1287,6 +1288,24 @@ static void svc_sock_detach(struct svc_xprt *xprt) | |||
1287 | sk->sk_state_change = svsk->sk_ostate; | 1288 | sk->sk_state_change = svsk->sk_ostate; |
1288 | sk->sk_data_ready = svsk->sk_odata; | 1289 | sk->sk_data_ready = svsk->sk_odata; |
1289 | sk->sk_write_space = svsk->sk_owspace; | 1290 | sk->sk_write_space = svsk->sk_owspace; |
1291 | |||
1292 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | ||
1293 | wake_up_interruptible(sk->sk_sleep); | ||
1294 | } | ||
1295 | |||
1296 | /* | ||
1297 | * Disconnect the socket, and reset the callbacks | ||
1298 | */ | ||
1299 | static void svc_tcp_sock_detach(struct svc_xprt *xprt) | ||
1300 | { | ||
1301 | struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt); | ||
1302 | |||
1303 | dprintk("svc: svc_tcp_sock_detach(%p)\n", svsk); | ||
1304 | |||
1305 | svc_sock_detach(xprt); | ||
1306 | |||
1307 | if (!test_bit(XPT_LISTENER, &xprt->xpt_flags)) | ||
1308 | kernel_sock_shutdown(svsk->sk_sock, SHUT_RDWR); | ||
1290 | } | 1309 | } |
1291 | 1310 | ||
1292 | /* | 1311 | /* |