FAILED: patch "[PATCH] SUNRPC: Ensure we flush any closed sockets before" failed to apply to 5.10-stable tree
Subsystems (6)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f00432063db1a0db484e85193eccc6845435b80e Mon Sep 17 00:00:00 2001
From: Trond Myklebust <[email protected]>
Date: Sun, 3 Apr 2022 15:58:11 -0400
Subject: [PATCH] SUNRPC: Ensure we flush any closed sockets before
xs_xprt_free()
We must ensure that all sockets are closed before we call xprt_free() and release the reference to the net namespace. The problem is that calling fput() will defer closing the socket until delayed_fput() gets called.
Let's fix the situation by allowing rpciod and the transport teardown code (which runs on the system wq) to call __fput_sync(), and directly close the socket.
fs/file_table.c +1 -0
@@ -412,6 +412,7 @@ void __fput_sync(struct file *file) }EXPORT_SYMBOL (fput); +EXPORT_SYMBOL (__fput_sync);void __init files_init (void ) {
include/trace/events/sunrpc.h +0 -1
@@ -1004,7 +1004,6 @@ DEFINE_RPC_XPRT_LIFETIME_EVENT(connect);DEFINE_RPC_XPRT_LIFETIME_EVENT (disconnect_auto);DEFINE_RPC_XPRT_LIFETIME_EVENT (disconnect_done);DEFINE_RPC_XPRT_LIFETIME_EVENT (disconnect_force); -DEFINE_RPC_XPRT_LIFETIME_EVENT (disconnect_cleanup);DEFINE_RPC_XPRT_LIFETIME_EVENT (destroy); DECLARE_EVENT_CLASS(rpc_xprt_event,
net/sunrpc/xprt.c +1 -6
@@ -930,12 +930,7 @@ void xprt_connect(struct rpc_task *task)if (!xprt_lock_write (xprt, task))return ; -if (test_and_clear_bit (XPRT_CLOSE_WAIT , &xprt->state)) { -trace_xprt_disconnect_cleanup (xprt); - xprt->ops->close (xprt); - } - -if (!xprt_connected (xprt)) { +if (!xprt_connected (xprt) && !test_bit (XPRT_CLOSE_WAIT , &xprt->state)) { task->tk_rqstp->rq_connect_cookie = xprt->connect_cookie;rpc_sleep_on_timeout (&xprt->pending, task,NULL ,xprt_request_timeout (task->tk_rqstp));
net/sunrpc/xprtsock.c +13 -3
@@ -879,7 +879,7 @@ static int xs_local_send_request(struct rpc_rqst *req)/* Close the stream if the previous transmission was incomplete */ if (xs_send_request_was_aborted (transport, req)) { -xs_close (xprt); +xprt_force_disconnect (xprt);return -ENOTCONN ; }
@@ -915,7 +915,7 @@ static int xs_local_send_request(struct rpc_rqst *req) -status); fallthrough;case -EPIPE : -xs_close (xprt); +xprt_force_disconnect (xprt); status = -ENOTCONN ; }
@@ -1185,6 +1185,16 @@ static void xs_reset_transport(struct sock_xprt *transport)if (sk ==NULL )return ; +/* +* Make sure we're calling this in a context from which it is safe +* to call __fput_sync(). In practice that means rpciod and the +* system workqueue. +*/ +if (!(current->flags &PF_WQ_WORKER )) { +WARN_ON_ONCE (1 ); +set_bit (XPRT_CLOSE_WAIT , &xprt->state); +return ; + }if (atomic_read (&transport->xprt.swapper))sk_clear_memalloc (sk);
@@ -1208,7 +1218,7 @@ static void xs_reset_transport(struct sock_xprt *transport)mutex_unlock (&transport->recv_mutex);trace_rpc_socket_close (xprt, sock); -fput (filp); +__fput_sync (filp);xprt_disconnect_done (xprt); }