mirror of https://github.com/torvalds/linux.git
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 <linkinjeon@kernel.org>
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Fixes: 0626e6641f ("cifsd: add server handler for central processing and tranport layers")
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
afb4108c92
commit
cfe76fdbb9
|
|
@ -521,13 +521,13 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -542,6 +542,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
|||
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;
|
||||
|
|
@ -549,7 +550,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
|||
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;
|
||||
|
|
@ -559,6 +560,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
|||
if (wc->byte_len <
|
||||
offsetof(struct smb_direct_data_transfer, padding)) {
|
||||
put_recvmsg(t, recvmsg);
|
||||
smb_direct_disconnect_rdma_connection(t);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -567,6 +569,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
|||
if (wc->byte_len < sizeof(struct smb_direct_data_transfer) +
|
||||
(u64)data_length) {
|
||||
put_recvmsg(t, recvmsg);
|
||||
smb_direct_disconnect_rdma_connection(t);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -609,11 +612,16 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
|||
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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue