Skip to content

Commit cfe76fd

Browse files
metze-sambasmfrench
authored andcommitted
smb: server: let recv_done() consistently call put_recvmsg/smb_direct_disconnect_rdma_connection
We should call put_recvmsg() before smb_direct_disconnect_rdma_connection() in order to call it before waking up the callers. In all error cases we should call smb_direct_disconnect_rdma_connection() in order to avoid stale connections. Cc: Namjae Jeon <[email protected]> Cc: Steve French <[email protected]> Cc: Tom Talpey <[email protected]> Cc: [email protected] Cc: [email protected] Fixes: 0626e66 ("cifsd: add server handler for central processing and tranport layers") Signed-off-by: Stefan Metzmacher <[email protected]> Acked-by: Namjae Jeon <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent afb4108 commit cfe76fd

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

fs/smb/server/transport_rdma.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -521,13 +521,13 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
521521
t = recvmsg->transport;
522522

523523
if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) {
524+
put_recvmsg(t, recvmsg);
524525
if (wc->status != IB_WC_WR_FLUSH_ERR) {
525526
pr_err("Recv error. status='%s (%d)' opcode=%d\n",
526527
ib_wc_status_msg(wc->status), wc->status,
527528
wc->opcode);
528529
smb_direct_disconnect_rdma_connection(t);
529530
}
530-
put_recvmsg(t, recvmsg);
531531
return;
532532
}
533533

@@ -542,14 +542,15 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
542542
case SMB_DIRECT_MSG_NEGOTIATE_REQ:
543543
if (wc->byte_len < sizeof(struct smb_direct_negotiate_req)) {
544544
put_recvmsg(t, recvmsg);
545+
smb_direct_disconnect_rdma_connection(t);
545546
return;
546547
}
547548
t->negotiation_requested = true;
548549
t->full_packet_received = true;
549550
t->status = SMB_DIRECT_CS_CONNECTED;
550551
enqueue_reassembly(t, recvmsg, 0);
551552
wake_up_interruptible(&t->wait_status);
552-
break;
553+
return;
553554
case SMB_DIRECT_MSG_DATA_TRANSFER: {
554555
struct smb_direct_data_transfer *data_transfer =
555556
(struct smb_direct_data_transfer *)recvmsg->packet;
@@ -559,6 +560,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
559560
if (wc->byte_len <
560561
offsetof(struct smb_direct_data_transfer, padding)) {
561562
put_recvmsg(t, recvmsg);
563+
smb_direct_disconnect_rdma_connection(t);
562564
return;
563565
}
564566

@@ -567,6 +569,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
567569
if (wc->byte_len < sizeof(struct smb_direct_data_transfer) +
568570
(u64)data_length) {
569571
put_recvmsg(t, recvmsg);
572+
smb_direct_disconnect_rdma_connection(t);
570573
return;
571574
}
572575

@@ -609,11 +612,16 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
609612
if (is_receive_credit_post_required(receive_credits, avail_recvmsg_count))
610613
mod_delayed_work(smb_direct_wq,
611614
&t->post_recv_credits_work, 0);
612-
break;
615+
return;
613616
}
614-
default:
615-
break;
616617
}
618+
619+
/*
620+
* This is an internal error!
621+
*/
622+
WARN_ON_ONCE(recvmsg->type != SMB_DIRECT_MSG_DATA_TRANSFER);
623+
put_recvmsg(t, recvmsg);
624+
smb_direct_disconnect_rdma_connection(t);
617625
}
618626

619627
static int smb_direct_post_recv(struct smb_direct_transport *t,

0 commit comments

Comments
 (0)