aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2011-10-11 06:41:32 -0400
committerSteve French <smfrench@gmail.com>2011-10-13 01:05:59 -0400
commita52c1eb7ae79f0a11511d49cfc00d2f9e576abea (patch)
treeaa8fb47c90a18f9556b9db559ae29711da891c17 /fs
parent21fed0d5b763b94a7d1568c27d0cce892ab8d43e (diff)
cifs: simplify read_from_socket
Move the iovec handling entirely into read_from_socket. That simplifies the code and gets rid of the special handling for header reads. With this we can also get rid of the "goto incomplete_rcv" label in the main demultiplex thread function since we can now treat header and non-header receives the same way. Also, make it return an int (since we'll never receive enough to worry about the sign bit anyway), and simply make it return the amount of bytes read or a negative error code. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs')
-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