Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6cc3b242 authored by Pavel Shilovsky's avatar Pavel Shilovsky Committed by Steve French
Browse files

CIFS: Fix SMB2+ interim response processing for read requests



For interim responses we only need to parse a header and update
a number credits. Now it is done for all SMB2+ command except
SMB2_READ which is wrong. Fix this by adding such processing.

Signed-off-by: default avatarPavel Shilovsky <pshilovsky@samba.org>
Tested-by: default avatarShirish Pargaonkar <shirishpargaonkar@gmail.com>
CC: Stable <stable@vger.kernel.org>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent deb7deff
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -1396,11 +1396,10 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
 * current bigbuf.
 */
static int
cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
discard_remaining_data(struct TCP_Server_Info *server)
{
	unsigned int rfclen = get_rfc1002_length(server->smallbuf);
	int remaining = rfclen + 4 - server->total_read;
	struct cifs_readdata *rdata = mid->callback_data;

	while (remaining > 0) {
		int length;
@@ -1414,10 +1413,20 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
		remaining -= length;
	}

	dequeue_mid(mid, rdata->result);
	return 0;
}

static int
cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
{
	int length;
	struct cifs_readdata *rdata = mid->callback_data;

	length = discard_remaining_data(server);
	dequeue_mid(mid, rdata->result);
	return length;
}

int
cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
{
@@ -1446,6 +1455,12 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
		return length;
	server->total_read += length;

	if (server->ops->is_status_pending &&
	    server->ops->is_status_pending(buf, server, 0)) {
		discard_remaining_data(server);
		return -1;
	}

	/* Was the SMB read successful? */
	rdata->result = server->ops->map_error(buf, false);
	if (rdata->result != 0) {