aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2011-10-19 15:29:23 -0400
committerJeff Layton <jlayton@redhat.com>2011-10-19 15:29:23 -0400
commit2a37ef94bb153fad13cbb091aab679d7c8b9a67f (patch)
tree5a8abdd9c6be0fe34444c579f8a4c3395a77c9e2 /fs/cifs/connect.c
parentffc00e27aa5d343eb71068c185cdbd65871ccdce (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.c101
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
322static bool 322static bool
323allocate_buffers(char **bigbuf, char **smallbuf, unsigned int size, 323allocate_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
577static struct mid_q_entry * 571static struct mid_q_entry *
578find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf, 572find_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 }
612multi_t2_fnd: 614multi_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);