SUNRPC: Don't leak sockets in xs_local_connect()
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Thu, 28 Apr 2022 15:08:13 +0000 (11:08 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 May 2022 10:32:37 +0000 (12:32 +0200)
commit aad41a7d7cf6c6fa804c872a2480f8e541da37cf upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/sunrpc/xprtsock.c

index 2fc8877334010ce02620651d37866adaec98301d..eec9569af4c51489399231bea45c0385ec6ce02c 100644 (file)
@@ -1967,6 +1967,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
@@ -1979,11 +1982,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)