diff options
-rw-r--r-- | fs/cifs/connect.c | 77 |
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 | ||
378 | static int | 378 | static int |
379 | read_from_socket(struct TCP_Server_Info *server, | 379 | read_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 | ||
443 | static bool | 429 | static 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 | ||
693 | incomplete_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 | ||