aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprtsock.c
diff options
context:
space:
mode:
authorRobert Richter <robert.richter@amd.com>2009-06-10 21:47:10 +0200
committerRobert Richter <robert.richter@amd.com>2009-06-10 21:47:10 +0200
commit0886751c5d8b19fcee2e65d34ae21c9111e652a9 (patch)
tree015e8c2b3d44d46e9e8fccd016340c51bc876d3b /net/sunrpc/xprtsock.c
parent7e4e0bd50e80df2fe5501f48f872448376cdd997 (diff)
parent07a2039b8eb0af4ff464efd3dfd95de5c02648c6 (diff)
downloadkernel_samsung_aries-0886751c5d8b19fcee2e65d34ae21c9111e652a9.zip
kernel_samsung_aries-0886751c5d8b19fcee2e65d34ae21c9111e652a9.tar.gz
kernel_samsung_aries-0886751c5d8b19fcee2e65d34ae21c9111e652a9.tar.bz2
Merge commit 'v2.6.30' into oprofile/master
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r--net/sunrpc/xprtsock.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index d40ff50..e185961 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -807,6 +807,9 @@ static void xs_reset_transport(struct sock_xprt *transport)
*
* This is used when all requests are complete; ie, no DRC state remains
* on the server we want to save.
+ *
+ * The caller _must_ be holding XPRT_LOCKED in order to avoid issues with
+ * xs_reset_transport() zeroing the socket from underneath a writer.
*/
static void xs_close(struct rpc_xprt *xprt)
{
@@ -824,6 +827,14 @@ static void xs_close(struct rpc_xprt *xprt)
xprt_disconnect_done(xprt);
}
+static void xs_tcp_close(struct rpc_xprt *xprt)
+{
+ if (test_and_clear_bit(XPRT_CONNECTION_CLOSE, &xprt->state))
+ xs_close(xprt);
+ else
+ xs_tcp_shutdown(xprt);
+}
+
/**
* xs_destroy - prepare to shutdown a transport
* @xprt: doomed transport
@@ -1772,6 +1783,15 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt,
xprt, -status, xprt_connected(xprt),
sock->sk->sk_state);
switch (status) {
+ default:
+ printk("%s: connect returned unhandled error %d\n",
+ __func__, status);
+ case -EADDRNOTAVAIL:
+ /* We're probably in TIME_WAIT. Get rid of existing socket,
+ * and retry
+ */
+ set_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
+ xprt_force_disconnect(xprt);
case -ECONNREFUSED:
case -ECONNRESET:
case -ENETUNREACH:
@@ -1782,10 +1802,6 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt,
xprt_clear_connecting(xprt);
return;
}
- /* get rid of existing socket, and retry */
- xs_tcp_shutdown(xprt);
- printk("%s: connect returned unhandled error %d\n",
- __func__, status);
out_eagain:
status = -EAGAIN;
out:
@@ -1994,7 +2010,7 @@ static struct rpc_xprt_ops xs_tcp_ops = {
.buf_free = rpc_free,
.send_request = xs_tcp_send_request,
.set_retrans_timeout = xprt_set_retrans_timeout_def,
- .close = xs_tcp_shutdown,
+ .close = xs_tcp_close,
.destroy = xs_destroy,
.print_stats = xs_tcp_print_stats,
};