提交 c24f57c6 编写于 作者: R Ronnie Sahlberg 提交者: Greg Kroah-Hartman

cifs: fix a credits leak for compund commands

[ Upstream commit cb5c2e63948451d38c977685fffc06e23beb4517 ]

When processing the mids for compounds we would only add credits based on
the last successful mid in the compound which would leak credits and
eventually triggering a re-connect.

Fix this by splitting the mid processing part into two loops instead of one
where the first loop just waits for all mids and then counts how many
credits we were granted for the whole compound.
Signed-off-by: NRonnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: NSteve French <stfrench@microsoft.com>
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 c016b6d3
...@@ -786,7 +786,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -786,7 +786,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
int i, j, rc = 0; int i, j, rc = 0;
int timeout, optype; int timeout, optype;
struct mid_q_entry *midQ[MAX_COMPOUND]; struct mid_q_entry *midQ[MAX_COMPOUND];
unsigned int credits = 1; unsigned int credits = 0;
char *buf; char *buf;
timeout = flags & CIFS_TIMEOUT_MASK; timeout = flags & CIFS_TIMEOUT_MASK;
...@@ -851,17 +851,20 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -851,17 +851,20 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
mutex_unlock(&ses->server->srv_mutex); mutex_unlock(&ses->server->srv_mutex);
for (i = 0; i < num_rqst; i++) { if (rc < 0)
if (rc < 0) goto out;
goto out;
if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) /*
smb311_update_preauth_hash(ses, rqst[i].rq_iov, * Compounding is never used during session establish.
rqst[i].rq_nvec); */
if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP))
smb311_update_preauth_hash(ses, rqst[0].rq_iov,
rqst[0].rq_nvec);
if (timeout == CIFS_ASYNC_OP) if (timeout == CIFS_ASYNC_OP)
goto out; goto out;
for (i = 0; i < num_rqst; i++) {
rc = wait_for_response(ses->server, midQ[i]); rc = wait_for_response(ses->server, midQ[i]);
if (rc != 0) { if (rc != 0) {
cifs_dbg(FYI, "Cancelling wait for mid %llu\n", cifs_dbg(FYI, "Cancelling wait for mid %llu\n",
...@@ -877,10 +880,21 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -877,10 +880,21 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
} }
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
} }
}
for (i = 0; i < num_rqst; i++)
if (midQ[i]->resp_buf)
credits += ses->server->ops->get_credits(midQ[i]);
if (!credits)
credits = 1;
for (i = 0; i < num_rqst; i++) {
if (rc < 0)
goto out;
rc = cifs_sync_mid_result(midQ[i], ses->server); rc = cifs_sync_mid_result(midQ[i], ses->server);
if (rc != 0) { if (rc != 0) {
add_credits(ses->server, 1, optype); add_credits(ses->server, credits, optype);
return rc; return rc;
} }
...@@ -901,23 +915,26 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -901,23 +915,26 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
else else
resp_buf_type[i] = CIFS_SMALL_BUFFER; resp_buf_type[i] = CIFS_SMALL_BUFFER;
if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) {
struct kvec iov = {
.iov_base = resp_iov[i].iov_base,
.iov_len = resp_iov[i].iov_len
};
smb311_update_preauth_hash(ses, &iov, 1);
}
credits = ses->server->ops->get_credits(midQ[i]);
rc = ses->server->ops->check_receive(midQ[i], ses->server, rc = ses->server->ops->check_receive(midQ[i], ses->server,
flags & CIFS_LOG_ERROR); flags & CIFS_LOG_ERROR);
/* mark it so buf will not be freed by cifs_delete_mid */ /* mark it so buf will not be freed by cifs_delete_mid */
if ((flags & CIFS_NO_RESP) == 0) if ((flags & CIFS_NO_RESP) == 0)
midQ[i]->resp_buf = NULL; midQ[i]->resp_buf = NULL;
} }
/*
* Compounding is never used during session establish.
*/
if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) {
struct kvec iov = {
.iov_base = resp_iov[0].iov_base,
.iov_len = resp_iov[0].iov_len
};
smb311_update_preauth_hash(ses, &iov, 1);
}
out: out:
/* /*
* This will dequeue all mids. After this it is important that the * This will dequeue all mids. After this it is important that the
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册