diff options
author | Jeff Layton <jlayton@redhat.com> | 2011-10-19 15:29:23 -0400 |
---|---|---|
committer | Jeff Layton <jlayton@redhat.com> | 2011-10-19 15:29:23 -0400 |
commit | 2a37ef94bb153fad13cbb091aab679d7c8b9a67f (patch) | |
tree | 5a8abdd9c6be0fe34444c579f8a4c3395a77c9e2 /fs/cifs/connect.c | |
parent | ffc00e27aa5d343eb71068c185cdbd65871ccdce (diff) |
cifs: move buffer pointers into TCP_Server_Info
We have several functions that need to access these pointers. Currently
that's done with a lot of double pointer passing. Instead, move them
into the TCP_Server_Info and simplify the handling.
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, 46 insertions, 55 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 8d5a61561909..8918f935bf07 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -320,27 +320,24 @@ requeue_echo: | |||
320 | } | 320 | } |
321 | 321 | ||
322 | static bool | 322 | static bool |
323 | allocate_buffers(char **bigbuf, char **smallbuf, unsigned int size, | 323 | allocate_buffers(struct TCP_Server_Info *server) |
324 | bool is_large_buf) | ||
325 | { | 324 | { |
326 | char *bbuf = *bigbuf, *sbuf = *smallbuf; | 325 | if (!server->bigbuf) { |
327 | 326 | server->bigbuf = (char *)cifs_buf_get(); | |
328 | if (bbuf == NULL) { | 327 | if (!server->bigbuf) { |
329 | bbuf = (char *)cifs_buf_get(); | ||
330 | if (!bbuf) { | ||
331 | cERROR(1, "No memory for large SMB response"); | 328 | cERROR(1, "No memory for large SMB response"); |
332 | msleep(3000); | 329 | msleep(3000); |
333 | /* retry will check if exiting */ | 330 | /* retry will check if exiting */ |
334 | return false; | 331 | return false; |
335 | } | 332 | } |
336 | } else if (is_large_buf) { | 333 | } else if (server->large_buf) { |
337 | /* we are reusing a dirty large buf, clear its start */ | 334 | /* we are reusing a dirty large buf, clear its start */ |
338 | memset(bbuf, 0, size); | 335 | memset(server->bigbuf, 0, sizeof(struct smb_hdr)); |
339 | } | 336 | } |
340 | 337 | ||
341 | if (sbuf == NULL) { | 338 | if (!server->smallbuf) { |
342 | sbuf = (char *)cifs_small_buf_get(); | 339 | server->smallbuf = (char *)cifs_small_buf_get(); |
343 | if (!sbuf) { | 340 | if (!server->smallbuf) { |
344 | cERROR(1, "No memory for SMB response"); | 341 | cERROR(1, "No memory for SMB response"); |
345 | msleep(1000); | 342 | msleep(1000); |
346 | /* retry will check if exiting */ | 343 | /* retry will check if exiting */ |
@@ -349,12 +346,9 @@ allocate_buffers(char **bigbuf, char **smallbuf, unsigned int size, | |||
349 | /* beginning of smb buffer is cleared in our buf_get */ | 346 | /* beginning of smb buffer is cleared in our buf_get */ |
350 | } else { | 347 | } else { |
351 | /* if existing small buf clear beginning */ | 348 | /* if existing small buf clear beginning */ |
352 | memset(sbuf, 0, size); | 349 | memset(server->smallbuf, 0, sizeof(struct smb_hdr)); |
353 | } | 350 | } |
354 | 351 | ||
355 | *bigbuf = bbuf; | ||
356 | *smallbuf = sbuf; | ||
357 | |||
358 | return true; | 352 | return true; |
359 | } | 353 | } |
360 | 354 | ||
@@ -576,7 +570,7 @@ dequeue_mid(struct mid_q_entry *mid, int malformed) | |||
576 | 570 | ||
577 | static struct mid_q_entry * | 571 | static struct mid_q_entry * |
578 | find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf, | 572 | find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf, |
579 | int malformed, bool is_large_buf, char **bigbuf) | 573 | int malformed) |
580 | { | 574 | { |
581 | struct mid_q_entry *mid = NULL; | 575 | struct mid_q_entry *mid = NULL; |
582 | 576 | ||
@@ -596,19 +590,27 @@ find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf, | |||
596 | mid->multiEnd = true; | 590 | mid->multiEnd = true; |
597 | goto multi_t2_fnd; | 591 | goto multi_t2_fnd; |
598 | } | 592 | } |
599 | if (!is_large_buf) { | 593 | if (!server->large_buf) { |
600 | /*FIXME: switch to already allocated largebuf?*/ | 594 | /*FIXME: switch to already allocated largebuf?*/ |
601 | cERROR(1, "1st trans2 resp needs bigbuf"); | 595 | cERROR(1, "1st trans2 resp needs bigbuf"); |
602 | } else { | 596 | } else { |
603 | /* Have first buffer */ | 597 | /* Have first buffer */ |
604 | mid->resp_buf = buf; | 598 | mid->resp_buf = buf; |
605 | mid->largeBuf = true; | 599 | mid->largeBuf = true; |
606 | *bigbuf = NULL; | 600 | server->bigbuf = NULL; |
607 | } | 601 | } |
608 | return mid; | 602 | return mid; |
609 | } | 603 | } |
610 | mid->resp_buf = buf; | 604 | mid->resp_buf = buf; |
611 | mid->largeBuf = is_large_buf; | 605 | mid->largeBuf = server->large_buf; |
606 | /* Was previous buf put in mpx struct for multi-rsp? */ | ||
607 | if (!mid->multiRsp) { | ||
608 | /* smb buffer will be freed by user thread */ | ||
609 | if (server->large_buf) | ||
610 | server->bigbuf = NULL; | ||
611 | else | ||
612 | server->smallbuf = NULL; | ||
613 | } | ||
612 | multi_t2_fnd: | 614 | multi_t2_fnd: |
613 | dequeue_mid(mid, malformed); | 615 | dequeue_mid(mid, malformed); |
614 | return mid; | 616 | return mid; |
@@ -715,12 +717,11 @@ cifs_demultiplex_thread(void *p) | |||
715 | { | 717 | { |
716 | int length; | 718 | int length; |
717 | struct TCP_Server_Info *server = p; | 719 | struct TCP_Server_Info *server = p; |
718 | unsigned int pdu_length, total_read; | 720 | unsigned int pdu_length; |
719 | char *buf = NULL, *bigbuf = NULL, *smallbuf = NULL; | 721 | char *buf = NULL; |
720 | struct smb_hdr *smb_buffer = NULL; | 722 | struct smb_hdr *smb_buffer = NULL; |
721 | struct task_struct *task_to_wake = NULL; | 723 | struct task_struct *task_to_wake = NULL; |
722 | struct mid_q_entry *mid_entry; | 724 | struct mid_q_entry *mid_entry; |
723 | bool isLargeBuf = false; | ||
724 | 725 | ||
725 | current->flags |= PF_MEMALLOC; | 726 | current->flags |= PF_MEMALLOC; |
726 | cFYI(1, "Demultiplex PID: %d", task_pid_nr(current)); | 727 | cFYI(1, "Demultiplex PID: %d", task_pid_nr(current)); |
@@ -735,19 +736,18 @@ cifs_demultiplex_thread(void *p) | |||
735 | if (try_to_freeze()) | 736 | if (try_to_freeze()) |
736 | continue; | 737 | continue; |
737 | 738 | ||
738 | if (!allocate_buffers(&bigbuf, &smallbuf, | 739 | if (!allocate_buffers(server)) |
739 | sizeof(struct smb_hdr), isLargeBuf)) | ||
740 | continue; | 740 | continue; |
741 | 741 | ||
742 | isLargeBuf = false; | 742 | server->large_buf = false; |
743 | smb_buffer = (struct smb_hdr *)smallbuf; | 743 | smb_buffer = (struct smb_hdr *)server->smallbuf; |
744 | buf = smallbuf; | 744 | buf = server->smallbuf; |
745 | pdu_length = 4; /* enough to get RFC1001 header */ | 745 | pdu_length = 4; /* enough to get RFC1001 header */ |
746 | 746 | ||
747 | length = read_from_socket(server, buf, pdu_length); | 747 | length = read_from_socket(server, buf, pdu_length); |
748 | if (length < 0) | 748 | if (length < 0) |
749 | continue; | 749 | continue; |
750 | total_read = length; | 750 | server->total_read = length; |
751 | 751 | ||
752 | /* | 752 | /* |
753 | * The right amount was read from socket - 4 bytes, | 753 | * The right amount was read from socket - 4 bytes, |
@@ -773,7 +773,7 @@ cifs_demultiplex_thread(void *p) | |||
773 | sizeof(struct smb_hdr) - 1 - 4); | 773 | sizeof(struct smb_hdr) - 1 - 4); |
774 | if (length < 0) | 774 | if (length < 0) |
775 | continue; | 775 | continue; |
776 | total_read += length; | 776 | server->total_read += length; |
777 | 777 | ||
778 | if (pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { | 778 | if (pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { |
779 | cERROR(1, "SMB response too long (%u bytes)", | 779 | cERROR(1, "SMB response too long (%u bytes)", |
@@ -785,10 +785,11 @@ cifs_demultiplex_thread(void *p) | |||
785 | 785 | ||
786 | /* else length ok */ | 786 | /* else length ok */ |
787 | if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { | 787 | if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { |
788 | isLargeBuf = true; | 788 | server->large_buf = true; |
789 | memcpy(bigbuf, smallbuf, total_read); | 789 | memcpy(server->bigbuf, server->smallbuf, |
790 | smb_buffer = (struct smb_hdr *)bigbuf; | 790 | server->total_read); |
791 | buf = bigbuf; | 791 | smb_buffer = (struct smb_hdr *)server->bigbuf; |
792 | buf = server->bigbuf; | ||
792 | } | 793 | } |
793 | 794 | ||
794 | /* now read the rest */ | 795 | /* now read the rest */ |
@@ -797,9 +798,9 @@ cifs_demultiplex_thread(void *p) | |||
797 | pdu_length - sizeof(struct smb_hdr) + 1 + 4); | 798 | pdu_length - sizeof(struct smb_hdr) + 1 + 4); |
798 | if (length < 0) | 799 | if (length < 0) |
799 | continue; | 800 | continue; |
800 | total_read += length; | 801 | server->total_read += length; |
801 | 802 | ||
802 | dump_smb(smb_buffer, total_read); | 803 | dump_smb(smb_buffer, server->total_read); |
803 | 804 | ||
804 | /* | 805 | /* |
805 | * We know that we received enough to get to the MID as we | 806 | * We know that we received enough to get to the MID as we |
@@ -810,28 +811,18 @@ cifs_demultiplex_thread(void *p) | |||
810 | * 48 bytes is enough to display the header and a little bit | 811 | * 48 bytes is enough to display the header and a little bit |
811 | * into the payload for debugging purposes. | 812 | * into the payload for debugging purposes. |
812 | */ | 813 | */ |
813 | length = checkSMB(smb_buffer, smb_buffer->Mid, total_read); | 814 | length = checkSMB(smb_buffer, smb_buffer->Mid, |
815 | server->total_read); | ||
814 | if (length != 0) | 816 | if (length != 0) |
815 | cifs_dump_mem("Bad SMB: ", buf, | 817 | cifs_dump_mem("Bad SMB: ", buf, |
816 | min_t(unsigned int, total_read, 48)); | 818 | min_t(unsigned int, server->total_read, 48)); |
817 | 819 | ||
818 | server->lstrp = jiffies; | 820 | server->lstrp = jiffies; |
819 | 821 | ||
820 | mid_entry = find_cifs_mid(server, smb_buffer, length, | 822 | mid_entry = find_cifs_mid(server, smb_buffer, length); |
821 | isLargeBuf, &bigbuf); | ||
822 | if (mid_entry != NULL) { | 823 | if (mid_entry != NULL) { |
823 | if (mid_entry->multiRsp && !mid_entry->multiEnd) | 824 | if (!mid_entry->multiRsp || mid_entry->multiEnd) |
824 | continue; | 825 | mid_entry->callback(mid_entry); |
825 | |||
826 | /* Was previous buf put in mpx struct for multi-rsp? */ | ||
827 | if (!mid_entry->multiRsp) { | ||
828 | /* smb buffer will be freed by user thread */ | ||
829 | if (isLargeBuf) | ||
830 | bigbuf = NULL; | ||
831 | else | ||
832 | smallbuf = NULL; | ||
833 | } | ||
834 | mid_entry->callback(mid_entry); | ||
835 | } else if (length != 0) { | 826 | } else if (length != 0) { |
836 | /* response sanity checks failed */ | 827 | /* response sanity checks failed */ |
837 | continue; | 828 | continue; |
@@ -849,9 +840,9 @@ cifs_demultiplex_thread(void *p) | |||
849 | } /* end while !EXITING */ | 840 | } /* end while !EXITING */ |
850 | 841 | ||
851 | /* buffer usually freed in free_mid - need to free it here on exit */ | 842 | /* buffer usually freed in free_mid - need to free it here on exit */ |
852 | cifs_buf_release(bigbuf); | 843 | cifs_buf_release(server->bigbuf); |
853 | if (smallbuf) /* no sense logging a debug message if NULL */ | 844 | if (server->smallbuf) /* no sense logging a debug message if NULL */ |
854 | cifs_small_buf_release(smallbuf); | 845 | cifs_small_buf_release(server->smallbuf); |
855 | 846 | ||
856 | task_to_wake = xchg(&server->tsk, NULL); | 847 | task_to_wake = xchg(&server->tsk, NULL); |
857 | clean_demultiplex_info(server); | 848 | clean_demultiplex_info(server); |