forked from luck/tmp_suning_uos_patched
SUNRPC: Ensure we release the TCP socket once it has been closed
This fixes a regression introduced by commit caf4ccd4e8
("SUNRPC:
Make xs_tcp_close() do a socket shutdown rather than a sock_release").
Prior to that commit, the autoclose feature would ensure that an
idle connection would result in the socket being both disconnected and
released, whereas now only gets disconnected.
While the current behaviour is harmless, it does leave the port bound
until either RPC traffic resumes or the RPC client is shut down.
Reported-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
parent
3832591e6f
commit
4876cc779f
|
@ -611,8 +611,8 @@ static void xprt_autoclose(struct work_struct *work)
|
|||
struct rpc_xprt *xprt =
|
||||
container_of(work, struct rpc_xprt, task_cleanup);
|
||||
|
||||
xprt->ops->close(xprt);
|
||||
clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
|
||||
xprt->ops->close(xprt);
|
||||
xprt_release_write(xprt, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -622,24 +622,6 @@ static int xs_udp_send_request(struct rpc_task *task)
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* xs_tcp_shutdown - gracefully shut down a TCP socket
|
||||
* @xprt: transport
|
||||
*
|
||||
* Initiates a graceful shutdown of the TCP socket by calling the
|
||||
* equivalent of shutdown(SHUT_RDWR);
|
||||
*/
|
||||
static void xs_tcp_shutdown(struct rpc_xprt *xprt)
|
||||
{
|
||||
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
||||
struct socket *sock = transport->sock;
|
||||
|
||||
if (sock != NULL) {
|
||||
kernel_sock_shutdown(sock, SHUT_RDWR);
|
||||
trace_rpc_socket_shutdown(xprt, sock);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* xs_tcp_send_request - write an RPC request to a TCP socket
|
||||
* @task: address of RPC task that manages the state of an RPC request
|
||||
|
@ -786,6 +768,7 @@ static void xs_sock_mark_closed(struct rpc_xprt *xprt)
|
|||
xs_sock_reset_connection_flags(xprt);
|
||||
/* Mark transport as closed and wake up all pending tasks */
|
||||
xprt_disconnect_done(xprt);
|
||||
xprt_force_disconnect(xprt);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2103,6 +2086,27 @@ static void xs_udp_setup_socket(struct work_struct *work)
|
|||
xprt_wake_pending_tasks(xprt, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* xs_tcp_shutdown - gracefully shut down a TCP socket
|
||||
* @xprt: transport
|
||||
*
|
||||
* Initiates a graceful shutdown of the TCP socket by calling the
|
||||
* equivalent of shutdown(SHUT_RDWR);
|
||||
*/
|
||||
static void xs_tcp_shutdown(struct rpc_xprt *xprt)
|
||||
{
|
||||
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
||||
struct socket *sock = transport->sock;
|
||||
|
||||
if (sock == NULL)
|
||||
return;
|
||||
if (xprt_connected(xprt)) {
|
||||
kernel_sock_shutdown(sock, SHUT_RDWR);
|
||||
trace_rpc_socket_shutdown(xprt, sock);
|
||||
} else
|
||||
xs_reset_transport(transport);
|
||||
}
|
||||
|
||||
static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
|
||||
{
|
||||
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
||||
|
|
Loading…
Reference in New Issue
Block a user