Message ID | 20220428153001.9545-1-trondmy@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/2] SUNRPC: Don't leak sockets in xs_local_connect() | expand |
在 2022/4/28 23:30, trondmy@kernel.org 写道: > From: Trond Myklebust <trond.myklebust@hammerspace.com> > > If there is still a closed socket associated with the transport, then we > need to trigger an autoclose before we can set up a new connection. > > Reported-by: wanghai (M) <wanghai38@huawei.com> > Fixes: f00432063db1 ("SUNRPC: Ensure we flush any closed sockets before xs_xprt_free()") > Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> > --- > net/sunrpc/xprtsock.c | 11 ++++++++++- > 1 file changed, 10 insertions(+), 1 deletion(-) Hi, Trond. Thank you for taking the time to help! I tested it with this patch and found that the problem still exists. The path of the sock leak is as follows and is not in xs_local_connect() write_ports nfsd_create_serv svc_bind rpcb_create_local rpcb_create_local_unix rpc_create xprt_create_transport xs_setup_local xs_local_setup_socket > diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c > index 8ab64ea46870..f9849b297ea3 100644 > --- a/net/sunrpc/xprtsock.c > +++ b/net/sunrpc/xprtsock.c > @@ -1950,6 +1950,9 @@ static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task) > struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); > int ret; > > + if (transport->file) > + goto force_disconnect; > + > if (RPC_IS_ASYNC(task)) { > /* > * We want the AF_LOCAL connect to be resolved in the > @@ -1962,11 +1965,17 @@ static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task) > */ > task->tk_rpc_status = -ENOTCONN; > rpc_exit(task, -ENOTCONN); > - return; > + goto out_wake; > } > ret = xs_local_setup_socket(transport); > if (ret && !RPC_IS_SOFTCONN(task)) > msleep_interruptible(15000); > + return; > +force_disconnect: > + xprt_force_disconnect(xprt); > +out_wake: > + xprt_clear_connecting(xprt); > + xprt_wake_pending_tasks(xprt, -ENOTCONN); > } > > #if IS_ENABLED(CONFIG_SUNRPC_SWAP)
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 8ab64ea46870..f9849b297ea3 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1950,6 +1950,9 @@ static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task) struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); int ret; + if (transport->file) + goto force_disconnect; + if (RPC_IS_ASYNC(task)) { /* * We want the AF_LOCAL connect to be resolved in the @@ -1962,11 +1965,17 @@ static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task) */ task->tk_rpc_status = -ENOTCONN; rpc_exit(task, -ENOTCONN); - return; + goto out_wake; } ret = xs_local_setup_socket(transport); if (ret && !RPC_IS_SOFTCONN(task)) msleep_interruptible(15000); + return; +force_disconnect: + xprt_force_disconnect(xprt); +out_wake: + xprt_clear_connecting(xprt); + xprt_wake_pending_tasks(xprt, -ENOTCONN); } #if IS_ENABLED(CONFIG_SUNRPC_SWAP)