From: Pavel Shilovsky Date: Wed, 23 Jan 2019 00:50:21 +0000 (-0800) Subject: CIFS: Fix credit calculations in compound mid callback X-Git-Tag: v4.20.11~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7cb453e5a88169b2a5cec1e00778fc969efd1a77;p=thirdparty%2Fkernel%2Fstable.git CIFS: Fix credit calculations in compound mid callback [ Upstream commit 3d3003fce8e837acc4e3960fe3cbabebc356dcb5 ] The current code doesn't do proper accounting for credits in SMB1 case: it adds one credit per response only if we get a complete response while it needs to return it unconditionally. Fix this and also include malformed responses for SMB2+ into accounting for credits because such responses have Credit Granted field, thus nothing prevents to get a proper credit value from them. Signed-off-by: Pavel Shilovsky Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French Signed-off-by: Sasha Levin --- diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index d7dd7d38fad61..aa71e620f3cd8 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -154,7 +154,11 @@ smb2_get_credits(struct mid_q_entry *mid) { struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)mid->resp_buf; - return le16_to_cpu(shdr->CreditRequest); + if (mid->mid_state == MID_RESPONSE_RECEIVED + || mid->mid_state == MID_RESPONSE_MALFORMED) + return le16_to_cpu(shdr->CreditRequest); + + return 0; } static int diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 0dab276eced84..6f937e8269100 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -784,17 +784,8 @@ static void cifs_compound_callback(struct mid_q_entry *mid) { struct TCP_Server_Info *server = mid->server; - unsigned int optype = mid->optype; - unsigned int credits_received = 0; - if (mid->mid_state == MID_RESPONSE_RECEIVED) { - if (mid->resp_buf) - credits_received = server->ops->get_credits(mid); - else - cifs_dbg(FYI, "Bad state for cancelled MID\n"); - } - - add_credits(server, credits_received, optype); + add_credits(server, server->ops->get_credits(mid), mid->optype); } static void