diff options
author | Jeff Layton <jlayton@redhat.com> | 2011-10-19 15:29:40 -0400 |
---|---|---|
committer | Jeff Layton <jlayton@redhat.com> | 2011-10-19 15:29:40 -0400 |
commit | e9097ab48978c89b9c0926e2ae5d49bf6ea91b18 (patch) | |
tree | 65627208271ae5601b6d65198a960167f6b25fe6 /fs/cifs/connect.c | |
parent | c8054ebdb6903208b83aa59c387b16d5129492d5 (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/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 101 |
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 | ||
707 | static int | 707 | static int |
708 | standard_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 | |||
762 | static int | ||
708 | cifs_demultiplex_thread(void *p) | 763 | cifs_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)); |