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)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Thu, 28 Apr 2022 15:28:37 +0000 (11:28 -0400)
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

index 8ab64ea..f9849b2 100644 (file)
@@ -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)