From: Stefan Metzmacher Date: Fri, 8 Aug 2025 16:48:15 +0000 (+0200) Subject: smb: client: use status_wait and SMBDIRECT_SOCKET_RESOLVE_{ADDR,ROUTE}_RUNNING for... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4ff3fa4e4aa78c3aa9083a8d448f8af4f0740df7;p=thirdparty%2Fkernel%2Fstable.git smb: client: use status_wait and SMBDIRECT_SOCKET_RESOLVE_{ADDR,ROUTE}_RUNNING for completion 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 Cc: Tom Talpey Cc: Long Li Cc: linux-cifs@vger.kernel.org Cc: samba-technical@lists.samba.org Acked-by: Namjae Jeon Signed-off-by: Stefan Metzmacher Signed-off-by: Steve French --- diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c index cfb45bc993766..556beec3f430f 100644 --- a/fs/smb/client/smbdirect.c +++ b/fs/smb/client/smbdirect.c @@ -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); diff --git a/fs/smb/client/smbdirect.h b/fs/smb/client/smbdirect.h index c9b0c6b61e7e5..82b1d936e8008 100644 --- a/fs/smb/client/smbdirect.h +++ b/fs/smb/client/smbdirect.h @@ -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;