[PATCH 4/8] cifs: update receive_encrypted_standard to handle compounded responses

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Ronnie Sahlberg <lsahlber@xxxxxxxxxx>
---
 fs/cifs/smb2ops.c | 39 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 3 deletions(-)

diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 81ff2bd6ceaa..10b888b954e4 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -2930,11 +2930,14 @@ static int
 receive_encrypted_standard(struct TCP_Server_Info *server,
 			   struct mid_q_entry **mid)
 {
-	int length;
+	int ret, length;
 	char *buf = server->smallbuf;
+	struct smb2_sync_hdr *shdr;
 	unsigned int pdu_length = server->pdu_size;
 	unsigned int buf_size;
 	struct mid_q_entry *mid_entry;
+	int next_is_large;
+	char *next_buffer = NULL;
 
 	/* switch to large buffer if too big for a small one */
 	if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE) {
@@ -2955,6 +2958,21 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
 	if (length)
 		return length;
 
+	next_is_large = server->large_buf;
+ one_more:
+	shdr = (struct smb2_sync_hdr *)buf;
+	if (shdr->NextCommand) {
+		if (next_is_large) {
+			next_buffer = (char *)cifs_buf_get();
+			memcpy(next_buffer, server->bigbuf + shdr->NextCommand,
+			       pdu_length - shdr->NextCommand);
+		} else {
+			next_buffer = (char *)cifs_small_buf_get();
+			memcpy(next_buffer, server->smallbuf + shdr->NextCommand,
+			       pdu_length - shdr->NextCommand);
+		}
+	}
+
 	mid_entry = smb2_find_mid(server, buf);
 	if (mid_entry == NULL)
 		cifs_dbg(FYI, "mid not found\n");
@@ -2962,13 +2980,28 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
 		cifs_dbg(FYI, "mid found\n");
 		mid_entry->decrypted = true;
 	}
+	mid_entry->resp_buf_size = server->pdu_size;
 
 	*mid = mid_entry;
 
 	if (mid_entry && mid_entry->handle)
-		return mid_entry->handle(server, mid_entry);
+		ret = mid_entry->handle(server, mid_entry);
+	else
+		ret = cifs_handle_standard(server, mid_entry);
+
+	if (ret == 0 && shdr->NextCommand) {
+		pdu_length -= shdr->NextCommand;
+		server->large_buf = next_is_large;
+		if (next_is_large) {
+			server->bigbuf = next_buffer;
+		} else {
+			server->smallbuf = next_buffer;
+		}
+		buf += shdr->NextCommand;
+		goto one_more;
+	}
 
-	return cifs_handle_standard(server, mid_entry);
+        return ret;
 }
 
 static int
-- 
2.13.3

--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux