]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
smb: client: use status_wait and SMBDIRECT_SOCKET_RESOLVE_{ADDR,ROUTE}_RUNNING for...
authorStefan Metzmacher <metze@samba.org>
Fri, 8 Aug 2025 16:48:15 +0000 (18:48 +0200)
committerSteve French <stfrench@microsoft.com>
Sun, 28 Sep 2025 23:29:48 +0000 (18:29 -0500)
We can use the state change from
SMBDIRECT_SOCKET_RESOLVE_{ADDR,ROUTE}_RUNNING
to the next state in order to wake the caller to do the next step.

Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/smbdirect.c
fs/smb/client/smbdirect.h

index cfb45bc9937666b4eb2204bacab5ca363919863a..556beec3f430fdf099c9037d9b52d27b149322ef 100644 (file)
@@ -217,31 +217,27 @@ static int smbd_conn_upcall(
        case RDMA_CM_EVENT_ADDR_RESOLVED:
                WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING);
                sc->status = SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED;
-               info->ri_rc = 0;
-               complete(&info->ri_done);
+               wake_up_interruptible(&info->status_wait);
                break;
 
        case RDMA_CM_EVENT_ROUTE_RESOLVED:
                WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING);
                sc->status = SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED;
-               info->ri_rc = 0;
-               complete(&info->ri_done);
+               wake_up_interruptible(&info->status_wait);
                break;
 
        case RDMA_CM_EVENT_ADDR_ERROR:
                log_rdma_event(ERR, "connecting failed event=%s\n", event_name);
                WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING);
                sc->status = SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED;
-               info->ri_rc = -EHOSTUNREACH;
-               complete(&info->ri_done);
+               wake_up_interruptible(&info->status_wait);
                break;
 
        case RDMA_CM_EVENT_ROUTE_ERROR:
                log_rdma_event(ERR, "connecting failed event=%s\n", event_name);
                WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING);
                sc->status = SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED;
-               info->ri_rc = -ENETUNREACH;
-               complete(&info->ri_done);
+               wake_up_interruptible(&info->status_wait);
                break;
 
        case RDMA_CM_EVENT_ESTABLISHED:
@@ -724,9 +720,6 @@ static struct rdma_cm_id *smbd_create_id(
 
        *sport = htons(port);
 
-       init_completion(&info->ri_done);
-       info->ri_rc = -ETIMEDOUT;
-
        WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ADDR_NEEDED);
        sc->status = SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING;
        rc = rdma_resolve_addr(id, NULL, (struct sockaddr *)dstaddr,
@@ -735,20 +728,26 @@ static struct rdma_cm_id *smbd_create_id(
                log_rdma_event(ERR, "rdma_resolve_addr() failed %i\n", rc);
                goto out;
        }
-       rc = wait_for_completion_interruptible_timeout(
-               &info->ri_done, msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT));
+       rc = wait_event_interruptible_timeout(
+               info->status_wait,
+               sc->status != SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING,
+               msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT));
        /* e.g. if interrupted returns -ERESTARTSYS */
        if (rc < 0) {
                log_rdma_event(ERR, "rdma_resolve_addr timeout rc: %i\n", rc);
                goto out;
        }
-       rc = info->ri_rc;
-       if (rc) {
+       if (sc->status == SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING) {
+               rc = -ETIMEDOUT;
+               log_rdma_event(ERR, "rdma_resolve_addr() completed %i\n", rc);
+               goto out;
+       }
+       if (sc->status != SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED) {
+               rc = -EHOSTUNREACH;
                log_rdma_event(ERR, "rdma_resolve_addr() completed %i\n", rc);
                goto out;
        }
 
-       info->ri_rc = -ETIMEDOUT;
        WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED);
        sc->status = SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING;
        rc = rdma_resolve_route(id, RDMA_RESOLVE_TIMEOUT);
@@ -756,15 +755,22 @@ static struct rdma_cm_id *smbd_create_id(
                log_rdma_event(ERR, "rdma_resolve_route() failed %i\n", rc);
                goto out;
        }
-       rc = wait_for_completion_interruptible_timeout(
-               &info->ri_done, msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT));
+       rc = wait_event_interruptible_timeout(
+               info->status_wait,
+               sc->status != SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING,
+               msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT));
        /* e.g. if interrupted returns -ERESTARTSYS */
        if (rc < 0)  {
                log_rdma_event(ERR, "rdma_resolve_addr timeout rc: %i\n", rc);
                goto out;
        }
-       rc = info->ri_rc;
-       if (rc) {
+       if (sc->status == SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING) {
+               rc = -ETIMEDOUT;
+               log_rdma_event(ERR, "rdma_resolve_route() completed %i\n", rc);
+               goto out;
+       }
+       if (sc->status != SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED) {
+               rc = -ENETUNREACH;
                log_rdma_event(ERR, "rdma_resolve_route() completed %i\n", rc);
                goto out;
        }
@@ -1703,6 +1709,8 @@ static struct smbd_connection *_smbd_get_connection(
        info->initiator_depth = 1;
        info->responder_resources = SMBD_CM_RESPONDER_RESOURCES;
 
+       init_waitqueue_head(&info->status_wait);
+
        sc->status = SMBDIRECT_SOCKET_CREATED;
        rc = smbd_ia_open(info, dstaddr, port);
        if (rc) {
@@ -1813,7 +1821,6 @@ static struct smbd_connection *_smbd_get_connection(
        log_rdma_event(INFO, "connecting to IP %pI4 port %d\n",
                &addr_in->sin_addr, port);
 
-       init_waitqueue_head(&info->status_wait);
        init_waitqueue_head(&sc->recv_io.reassembly.wait_queue);
 
        WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED);
index c9b0c6b61e7e5cfd49545edb6d16b911840a1e9c..82b1d936e80084038dac1eaa44b834391ee1ca15 100644 (file)
@@ -45,8 +45,6 @@ enum keep_alive_status {
 struct smbd_connection {
        struct smbdirect_socket socket;
 
-       int ri_rc;
-       struct completion ri_done;
        wait_queue_head_t status_wait;
 
        struct work_struct disconnect_work;