aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2011-10-19 15:29:40 -0400
committerJeff Layton <jlayton@redhat.com>2011-10-19 15:29:40 -0400
commite9097ab48978c89b9c0926e2ae5d49bf6ea91b18 (patch)
tree65627208271ae5601b6d65198a960167f6b25fe6 /fs/cifs
parentc8054ebdb6903208b83aa59c387b16d5129492d5 (diff)
cifs: break out 3rd receive phase into separate function
Move the entire 3rd phase of the receive codepath into a separate function in preparation for the addition of a pluggable receive function. Reviewed-and-Tested-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/connect.c101
1 files changed, 59 insertions, 42 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 52195bad5e67..f05dedda37c6 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -705,6 +705,61 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
705} 705}
706 706
707static int 707static int
708standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
709{
710 int length;
711 char *buf = server->smallbuf;
712 struct smb_hdr *smb_buffer = (struct smb_hdr *)buf;
713 unsigned int pdu_length = be32_to_cpu(smb_buffer->smb_buf_length);
714
715 /* make sure this will fit in a large buffer */
716 if (pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
717 cERROR(1, "SMB response too long (%u bytes)",
718 pdu_length);
719 cifs_reconnect(server);
720 wake_up(&server->response_q);
721 return -EAGAIN;
722 }
723
724 /* switch to large buffer if too big for a small one */
725 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
726 server->large_buf = true;
727 memcpy(server->bigbuf, server->smallbuf, server->total_read);
728 buf = server->bigbuf;
729 smb_buffer = (struct smb_hdr *)buf;
730 }
731
732 /* now read the rest */
733 length = read_from_socket(server,
734 buf + sizeof(struct smb_hdr) - 1,
735 pdu_length - sizeof(struct smb_hdr) + 1 + 4);
736 if (length < 0)
737 return length;
738 server->total_read += length;
739
740 dump_smb(smb_buffer, server->total_read);
741
742 /*
743 * We know that we received enough to get to the MID as we
744 * checked the pdu_length earlier. Now check to see
745 * if the rest of the header is OK. We borrow the length
746 * var for the rest of the loop to avoid a new stack var.
747 *
748 * 48 bytes is enough to display the header and a little bit
749 * into the payload for debugging purposes.
750 */
751 length = checkSMB(smb_buffer, smb_buffer->Mid, server->total_read);
752 if (length != 0)
753 cifs_dump_mem("Bad SMB: ", buf,
754 min_t(unsigned int, server->total_read, 48));
755
756 if (mid)
757 handle_mid(mid, server, smb_buffer, length);
758
759 return length;
760}
761
762static int
708cifs_demultiplex_thread(void *p) 763cifs_demultiplex_thread(void *p)
709{ 764{
710 int length; 765 int length;
@@ -769,57 +824,19 @@ cifs_demultiplex_thread(void *p)
769 824
770 mid_entry = find_mid(server, smb_buffer); 825 mid_entry = find_mid(server, smb_buffer);
771 826
772 if (pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 827 length = standard_receive3(server, mid_entry);
773 cERROR(1, "SMB response too long (%u bytes)", 828 if (length < 0)
774 pdu_length);
775 cifs_reconnect(server);
776 wake_up(&server->response_q);
777 continue; 829 continue;
778 }
779 830
780 /* else length ok */ 831 if (server->large_buf) {
781 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
782 server->large_buf = true;
783 memcpy(server->bigbuf, server->smallbuf,
784 server->total_read);
785 smb_buffer = (struct smb_hdr *)server->bigbuf;
786 buf = server->bigbuf; 832 buf = server->bigbuf;
833 smb_buffer = (struct smb_hdr *)buf;
787 } 834 }
788 835
789 /* now read the rest */
790 length = read_from_socket(server,
791 buf + sizeof(struct smb_hdr) - 1,
792 pdu_length - sizeof(struct smb_hdr) + 1 + 4);
793 if (length < 0)
794 continue;
795 server->total_read += length;
796
797 dump_smb(smb_buffer, server->total_read);
798
799 /*
800 * We know that we received enough to get to the MID as we
801 * checked the pdu_length earlier. Now check to see
802 * if the rest of the header is OK. We borrow the length
803 * var for the rest of the loop to avoid a new stack var.
804 *
805 * 48 bytes is enough to display the header and a little bit
806 * into the payload for debugging purposes.
807 */
808 length = checkSMB(smb_buffer, smb_buffer->Mid,
809 server->total_read);
810 if (length != 0)
811 cifs_dump_mem("Bad SMB: ", buf,
812 min_t(unsigned int, server->total_read, 48));
813
814 server->lstrp = jiffies; 836 server->lstrp = jiffies;
815
816 if (mid_entry != NULL) { 837 if (mid_entry != NULL) {
817 handle_mid(mid_entry, server, smb_buffer, length);
818 if (!mid_entry->multiRsp || mid_entry->multiEnd) 838 if (!mid_entry->multiRsp || mid_entry->multiEnd)
819 mid_entry->callback(mid_entry); 839 mid_entry->callback(mid_entry);
820 } else if (length != 0) {
821 /* response sanity checks failed */
822 continue;
823 } else if (!is_valid_oplock_break(smb_buffer, server)) { 840 } else if (!is_valid_oplock_break(smb_buffer, server)) {
824 cERROR(1, "No task to wake, unknown frame received! " 841 cERROR(1, "No task to wake, unknown frame received! "
825 "NumMids %d", atomic_read(&midCount)); 842 "NumMids %d", atomic_read(&midCount));