aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2011-10-19 15:28:57 -0400
committerJeff Layton <jlayton@redhat.com>2011-10-19 15:28:57 -0400
commit89482a56a079f01c2f4c709f8e23fbf7eeda1b43 (patch)
tree5b61c1e06da9bf78c71c871016909497b7cbe6e1 /fs/cifs/connect.c
parent1041e3f9919999b22c9c2a453aa0d92cd16b76ee (diff)
cifs: add a third receive phase to cifs_demultiplex_thread
Have the demultiplex thread receive just enough to get to the MID, and then find it before receiving the rest. Later, we'll use this to swap in a preallocated receive buffer for some calls. Reviewed-and-Tested-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index ee70075c5fb1..5308bc6e1248 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -746,11 +746,25 @@ cifs_demultiplex_thread(void *p)
746 if (!is_smb_response(server, buf[0])) 746 if (!is_smb_response(server, buf[0]))
747 continue; 747 continue;
748 748
749 /* check the length */ 749 /* make sure we have enough to get to the MID */
750 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) || 750 if (pdu_length < sizeof(struct smb_hdr) - 1 - 4) {
751 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) { 751 cERROR(1, "SMB response too short (%u bytes)",
752 cERROR(1, "Invalid size SMB length %d pdu_length %d", 752 pdu_length);
753 4, pdu_length + 4); 753 cifs_reconnect(server);
754 wake_up(&server->response_q);
755 continue;
756 }
757
758 /* read down to the MID */
759 length = read_from_socket(server, buf + 4,
760 sizeof(struct smb_hdr) - 1 - 4);
761 if (length < 0)
762 continue;
763 total_read += length;
764
765 if (pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
766 cERROR(1, "SMB response too long (%u bytes)",
767 pdu_length);
754 cifs_reconnect(server); 768 cifs_reconnect(server);
755 wake_up(&server->response_q); 769 wake_up(&server->response_q);
756 continue; 770 continue;
@@ -759,12 +773,15 @@ cifs_demultiplex_thread(void *p)
759 /* else length ok */ 773 /* else length ok */
760 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { 774 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
761 isLargeBuf = true; 775 isLargeBuf = true;
762 memcpy(bigbuf, smallbuf, 4); 776 memcpy(bigbuf, smallbuf, total_read);
763 smb_buffer = (struct smb_hdr *)bigbuf; 777 smb_buffer = (struct smb_hdr *)bigbuf;
764 buf = bigbuf; 778 buf = bigbuf;
765 } 779 }
766 780
767 length = read_from_socket(server, buf + 4, pdu_length); 781 /* now read the rest */
782 length = read_from_socket(server,
783 buf + sizeof(struct smb_hdr) - 1,
784 pdu_length - sizeof(struct smb_hdr) + 1 + 4);
768 if (length < 0) 785 if (length < 0)
769 continue; 786 continue;
770 total_read += length; 787 total_read += length;