Commit a743419f authored by Benjamin Coddington's avatar Benjamin Coddington Committed by Trond Myklebust

SUNRPC: Don't wake tasks during connection abort

When aborting a connection to preserve source ports, don't wake the task in
xs_error_report.  This allows tasks with RPC_TASK_SOFTCONN to succeed if the
connection needs to be re-established since it preserves the task's status
instead of setting it to the status of the aborting kernel_connect().

This may also avoid a potential conflict on the socket's lock.
Signed-off-by: default avatarBenjamin Coddington <bcodding@redhat.com>
Cc: stable@vger.kernel.org # 3.14+
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 8faaa6d5
...@@ -357,6 +357,7 @@ int xs_swapper(struct rpc_xprt *xprt, int enable); ...@@ -357,6 +357,7 @@ int xs_swapper(struct rpc_xprt *xprt, int enable);
#define XPRT_CONNECTION_ABORT (7) #define XPRT_CONNECTION_ABORT (7)
#define XPRT_CONNECTION_CLOSE (8) #define XPRT_CONNECTION_CLOSE (8)
#define XPRT_CONGESTED (9) #define XPRT_CONGESTED (9)
#define XPRT_CONNECTION_REUSE (10)
static inline void xprt_set_connected(struct rpc_xprt *xprt) static inline void xprt_set_connected(struct rpc_xprt *xprt)
{ {
......
...@@ -845,6 +845,8 @@ static void xs_error_report(struct sock *sk) ...@@ -845,6 +845,8 @@ static void xs_error_report(struct sock *sk)
dprintk("RPC: xs_error_report client %p, error=%d...\n", dprintk("RPC: xs_error_report client %p, error=%d...\n",
xprt, -err); xprt, -err);
trace_rpc_socket_error(xprt, sk->sk_socket, err); trace_rpc_socket_error(xprt, sk->sk_socket, err);
if (test_bit(XPRT_CONNECTION_REUSE, &xprt->state))
goto out;
xprt_wake_pending_tasks(xprt, err); xprt_wake_pending_tasks(xprt, err);
out: out:
read_unlock_bh(&sk->sk_callback_lock); read_unlock_bh(&sk->sk_callback_lock);
...@@ -2261,7 +2263,9 @@ static void xs_tcp_setup_socket(struct work_struct *work) ...@@ -2261,7 +2263,9 @@ static void xs_tcp_setup_socket(struct work_struct *work)
abort_and_exit = test_and_clear_bit(XPRT_CONNECTION_ABORT, abort_and_exit = test_and_clear_bit(XPRT_CONNECTION_ABORT,
&xprt->state); &xprt->state);
/* "close" the socket, preserving the local port */ /* "close" the socket, preserving the local port */
set_bit(XPRT_CONNECTION_REUSE, &xprt->state);
xs_tcp_reuse_connection(transport); xs_tcp_reuse_connection(transport);
clear_bit(XPRT_CONNECTION_REUSE, &xprt->state);
if (abort_and_exit) if (abort_and_exit)
goto out_eagain; goto out_eagain;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment