]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
smb: client: let recv_done() cleanup before notifying the callers.
authorStefan Metzmacher <metze@samba.org>
Mon, 4 Aug 2025 12:10:15 +0000 (14:10 +0200)
committerSteve French <stfrench@microsoft.com>
Wed, 6 Aug 2025 20:04:13 +0000 (15:04 -0500)
We should call put_receive_buffer() before waking up the callers.

For the internal error case of response->type being unexpected,
we now also call smbd_disconnect_rdma_connection() instead
of not waking up the callers at all.

Note that the SMBD_TRANSFER_DATA case still has problems,
which will be addressed in the next commit in order to make
it easier to review this one.

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
Fixes: f198186aa9bb ("CIFS: SMBD: Establish SMB Direct connection")
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/smbdirect.c

index 5690e8b3d101b0af79e75548756aa167f96c2333..d26b8cef82d65bd385bdc7c981094439b46f5bc4 100644 (file)
@@ -454,7 +454,6 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
        if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) {
                log_rdma_recv(INFO, "wc->status=%d opcode=%d\n",
                        wc->status, wc->opcode);
-               smbd_disconnect_rdma_connection(info);
                goto error;
        }
 
@@ -471,8 +470,9 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
                info->full_packet_received = true;
                info->negotiate_done =
                        process_negotiation_response(response, wc->byte_len);
+               put_receive_buffer(info, response);
                complete(&info->negotiate_completion);
-               break;
+               return;
 
        /* SMBD data transfer packet */
        case SMBD_TRANSFER_DATA:
@@ -529,14 +529,16 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
                }
 
                return;
-
-       default:
-               log_rdma_recv(ERR,
-                       "unexpected response type=%d\n", response->type);
        }
 
+       /*
+        * This is an internal error!
+        */
+       log_rdma_recv(ERR, "unexpected response type=%d\n", response->type);
+       WARN_ON_ONCE(response->type != SMBD_TRANSFER_DATA);
 error:
        put_receive_buffer(info, response);
+       smbd_disconnect_rdma_connection(info);
 }
 
 static struct rdma_cm_id *smbd_create_id(