summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/connect.c77
1 files changed, 24 insertions, 53 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 70dd2c418276..ff47c1842bec 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -376,35 +376,33 @@ server_unresponsive(struct TCP_Server_Info *server)
376} 376}
377 377
378static int 378static int
379read_from_socket(struct TCP_Server_Info *server, 379read_from_socket(struct TCP_Server_Info *server, char *buf,
380 struct kvec *iov, unsigned int to_read, 380 unsigned int to_read)
381 unsigned int *ptotal_read, bool is_header_read)
382{ 381{
383 int length, rc = 0; 382 int length = 0;
384 unsigned int total_read; 383 int total_read;
385 struct msghdr smb_msg; 384 struct msghdr smb_msg;
386 char *buf = iov->iov_base; 385 struct kvec iov;
387 386
388 smb_msg.msg_control = NULL; 387 smb_msg.msg_control = NULL;
389 smb_msg.msg_controllen = 0; 388 smb_msg.msg_controllen = 0;
390 389
391 for (total_read = 0; total_read < to_read; total_read += length) { 390 for (total_read = 0; to_read; total_read += length, to_read -= length) {
392 if (server_unresponsive(server)) { 391 if (server_unresponsive(server)) {
393 rc = 1; 392 total_read = -EAGAIN;
394 break; 393 break;
395 } 394 }
396 395
397 length = kernel_recvmsg(server->ssocket, &smb_msg, iov, 1, 396 iov.iov_base = buf + total_read;
398 to_read - total_read, 0); 397 iov.iov_len = to_read;
398 length = kernel_recvmsg(server->ssocket, &smb_msg, &iov, 1,
399 to_read, 0);
399 if (server->tcpStatus == CifsExiting) { 400 if (server->tcpStatus == CifsExiting) {
400 /* then will exit */ 401 total_read = -ESHUTDOWN;
401 rc = 2;
402 break; 402 break;
403 } else if (server->tcpStatus == CifsNeedReconnect) { 403 } else if (server->tcpStatus == CifsNeedReconnect) {
404 cifs_reconnect(server); 404 cifs_reconnect(server);
405 /* Reconnect wakes up rspns q */ 405 total_read = -EAGAIN;
406 /* Now we will reread sock */
407 rc = 1;
408 break; 406 break;
409 } else if (length == -ERESTARTSYS || 407 } else if (length == -ERESTARTSYS ||
410 length == -EAGAIN || 408 length == -EAGAIN ||
@@ -416,28 +414,16 @@ read_from_socket(struct TCP_Server_Info *server,
416 */ 414 */
417 usleep_range(1000, 2000); 415 usleep_range(1000, 2000);
418 length = 0; 416 length = 0;
419 if (!is_header_read) 417 continue;
420 continue;
421 /* Special handling for header read */
422 if (total_read) {
423 iov->iov_base = (to_read - total_read) +
424 buf;
425 iov->iov_len = to_read - total_read;
426 rc = 3;
427 } else
428 rc = 1;
429 break;
430 } else if (length <= 0) { 418 } else if (length <= 0) {
431 cERROR(1, "Received no data, expecting %d", 419 cFYI(1, "Received no data or error: expecting %d "
432 to_read - total_read); 420 "got %d", to_read, length);
433 cifs_reconnect(server); 421 cifs_reconnect(server);
434 rc = 1; 422 total_read = -EAGAIN;
435 break; 423 break;
436 } 424 }
437 } 425 }
438 426 return total_read;
439 *ptotal_read = total_read;
440 return rc;
441} 427}
442 428
443static bool 429static bool
@@ -658,12 +644,10 @@ cifs_demultiplex_thread(void *p)
658 unsigned int pdu_length, total_read; 644 unsigned int pdu_length, total_read;
659 char *buf = NULL, *bigbuf = NULL, *smallbuf = NULL; 645 char *buf = NULL, *bigbuf = NULL, *smallbuf = NULL;
660 struct smb_hdr *smb_buffer = NULL; 646 struct smb_hdr *smb_buffer = NULL;
661 struct kvec iov;
662 struct task_struct *task_to_wake = NULL; 647 struct task_struct *task_to_wake = NULL;
663 struct mid_q_entry *mid_entry; 648 struct mid_q_entry *mid_entry;
664 bool isLargeBuf = false; 649 bool isLargeBuf = false;
665 bool isMultiRsp = false; 650 bool isMultiRsp = false;
666 int rc;
667 651
668 current->flags |= PF_MEMALLOC; 652 current->flags |= PF_MEMALLOC;
669 cFYI(1, "Demultiplex PID: %d", task_pid_nr(current)); 653 cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
@@ -686,19 +670,12 @@ cifs_demultiplex_thread(void *p)
686 isMultiRsp = false; 670 isMultiRsp = false;
687 smb_buffer = (struct smb_hdr *)smallbuf; 671 smb_buffer = (struct smb_hdr *)smallbuf;
688 buf = smallbuf; 672 buf = smallbuf;
689 iov.iov_base = buf;
690 iov.iov_len = 4;
691 pdu_length = 4; /* enough to get RFC1001 header */ 673 pdu_length = 4; /* enough to get RFC1001 header */
692 674
693incomplete_rcv: 675 length = read_from_socket(server, buf, pdu_length);
694 rc = read_from_socket(server, &iov, pdu_length, 676 if (length < 0)
695 &total_read, true /* header read */);
696 if (rc == 3)
697 goto incomplete_rcv;
698 else if (rc == 2)
699 break;
700 else if (rc == 1)
701 continue; 677 continue;
678 total_read = length;
702 679
703 /* 680 /*
704 * The right amount was read from socket - 4 bytes, 681 * The right amount was read from socket - 4 bytes,
@@ -718,16 +695,10 @@ incomplete_rcv:
718 buf = bigbuf; 695 buf = bigbuf;
719 } 696 }
720 697
721 iov.iov_base = 4 + buf; 698 length = read_from_socket(server, buf + 4, pdu_length);
722 iov.iov_len = pdu_length; 699 if (length < 0)
723 rc = read_from_socket(server, &iov, pdu_length,
724 &total_read, false);
725 if (rc == 2)
726 break;
727 else if (rc == 1)
728 continue; 700 continue;
729 701 total_read += length;
730 total_read += 4; /* account for rfc1002 hdr */
731 702
732 dump_smb(smb_buffer, total_read); 703 dump_smb(smb_buffer, total_read);
733 704