t = recvmsg->transport;
 
        if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) {
+               put_recvmsg(t, recvmsg);
                if (wc->status != IB_WC_WR_FLUSH_ERR) {
                        pr_err("Recv error. status='%s (%d)' opcode=%d\n",
                               ib_wc_status_msg(wc->status), wc->status,
                               wc->opcode);
                        smb_direct_disconnect_rdma_connection(t);
                }
-               put_recvmsg(t, recvmsg);
                return;
        }
 
        case SMB_DIRECT_MSG_NEGOTIATE_REQ:
                if (wc->byte_len < sizeof(struct smb_direct_negotiate_req)) {
                        put_recvmsg(t, recvmsg);
+                       smb_direct_disconnect_rdma_connection(t);
                        return;
                }
                t->negotiation_requested = true;
                t->status = SMB_DIRECT_CS_CONNECTED;
                enqueue_reassembly(t, recvmsg, 0);
                wake_up_interruptible(&t->wait_status);
-               break;
+               return;
        case SMB_DIRECT_MSG_DATA_TRANSFER: {
                struct smb_direct_data_transfer *data_transfer =
                        (struct smb_direct_data_transfer *)recvmsg->packet;
                if (wc->byte_len <
                    offsetof(struct smb_direct_data_transfer, padding)) {
                        put_recvmsg(t, recvmsg);
+                       smb_direct_disconnect_rdma_connection(t);
                        return;
                }
 
                        if (wc->byte_len < sizeof(struct smb_direct_data_transfer) +
                            (u64)data_length) {
                                put_recvmsg(t, recvmsg);
+                               smb_direct_disconnect_rdma_connection(t);
                                return;
                        }
 
                if (is_receive_credit_post_required(receive_credits, avail_recvmsg_count))
                        mod_delayed_work(smb_direct_wq,
                                         &t->post_recv_credits_work, 0);
-               break;
+               return;
        }
-       default:
-               break;
        }
+
+       /*
+        * This is an internal error!
+        */
+       WARN_ON_ONCE(recvmsg->type != SMB_DIRECT_MSG_DATA_TRANSFER);
+       put_recvmsg(t, recvmsg);
+       smb_direct_disconnect_rdma_connection(t);
 }
 
 static int smb_direct_post_recv(struct smb_direct_transport *t,