|
@@ -767,23 +767,13 @@ static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *s
|
|
sk->sk_error_report = transport->old_error_report;
|
|
sk->sk_error_report = transport->old_error_report;
|
|
}
|
|
}
|
|
|
|
|
|
-/**
|
|
|
|
- * xs_close - close a socket
|
|
|
|
- * @xprt: transport
|
|
|
|
- *
|
|
|
|
- * This is used when all requests are complete; ie, no DRC state remains
|
|
|
|
- * on the server we want to save.
|
|
|
|
- */
|
|
|
|
-static void xs_close(struct rpc_xprt *xprt)
|
|
|
|
|
|
+static void xs_reset_transport(struct sock_xprt *transport)
|
|
{
|
|
{
|
|
- struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
|
|
|
struct socket *sock = transport->sock;
|
|
struct socket *sock = transport->sock;
|
|
struct sock *sk = transport->inet;
|
|
struct sock *sk = transport->inet;
|
|
|
|
|
|
- if (!sk)
|
|
|
|
- goto clear_close_wait;
|
|
|
|
-
|
|
|
|
- dprintk("RPC: xs_close xprt %p\n", xprt);
|
|
|
|
|
|
+ if (sk == NULL)
|
|
|
|
+ return;
|
|
|
|
|
|
write_lock_bh(&sk->sk_callback_lock);
|
|
write_lock_bh(&sk->sk_callback_lock);
|
|
transport->inet = NULL;
|
|
transport->inet = NULL;
|
|
@@ -797,7 +787,23 @@ static void xs_close(struct rpc_xprt *xprt)
|
|
sk->sk_no_check = 0;
|
|
sk->sk_no_check = 0;
|
|
|
|
|
|
sock_release(sock);
|
|
sock_release(sock);
|
|
-clear_close_wait:
|
|
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * xs_close - close a socket
|
|
|
|
+ * @xprt: transport
|
|
|
|
+ *
|
|
|
|
+ * This is used when all requests are complete; ie, no DRC state remains
|
|
|
|
+ * on the server we want to save.
|
|
|
|
+ */
|
|
|
|
+static void xs_close(struct rpc_xprt *xprt)
|
|
|
|
+{
|
|
|
|
+ struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
|
|
|
+
|
|
|
|
+ dprintk("RPC: xs_close xprt %p\n", xprt);
|
|
|
|
+
|
|
|
|
+ xs_reset_transport(transport);
|
|
|
|
+
|
|
smp_mb__before_clear_bit();
|
|
smp_mb__before_clear_bit();
|
|
clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
|
|
clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
|
|
clear_bit(XPRT_CLOSING, &xprt->state);
|
|
clear_bit(XPRT_CLOSING, &xprt->state);
|
|
@@ -1537,9 +1543,10 @@ static void xs_udp_connect_worker4(struct work_struct *work)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
/* Start by resetting any existing state */
|
|
/* Start by resetting any existing state */
|
|
- xs_close(xprt);
|
|
|
|
|
|
+ xs_reset_transport(transport);
|
|
|
|
|
|
- if ((err = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
|
|
|
|
|
|
+ err = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock);
|
|
|
|
+ if (err < 0) {
|
|
dprintk("RPC: can't create UDP transport socket (%d).\n", -err);
|
|
dprintk("RPC: can't create UDP transport socket (%d).\n", -err);
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
@@ -1578,9 +1585,10 @@ static void xs_udp_connect_worker6(struct work_struct *work)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
/* Start by resetting any existing state */
|
|
/* Start by resetting any existing state */
|
|
- xs_close(xprt);
|
|
|
|
|
|
+ xs_reset_transport(transport);
|
|
|
|
|
|
- if ((err = sock_create_kern(PF_INET6, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
|
|
|
|
|
|
+ err = sock_create_kern(PF_INET6, SOCK_DGRAM, IPPROTO_UDP, &sock);
|
|
|
|
+ if (err < 0) {
|
|
dprintk("RPC: can't create UDP transport socket (%d).\n", -err);
|
|
dprintk("RPC: can't create UDP transport socket (%d).\n", -err);
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|