diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/transport.c | 121 |
1 files changed, 43 insertions, 78 deletions
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 801726b11e1e..15059c7ef2ae 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -389,6 +389,42 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, | |||
389 | return rc; | 389 | return rc; |
390 | } | 390 | } |
391 | 391 | ||
392 | static int | ||
393 | sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) | ||
394 | { | ||
395 | int rc = 0; | ||
396 | |||
397 | spin_lock(&GlobalMid_Lock); | ||
398 | |||
399 | if (mid->resp_buf) { | ||
400 | spin_unlock(&GlobalMid_Lock); | ||
401 | return rc; | ||
402 | } | ||
403 | |||
404 | cERROR(1, "No response to cmd %d mid %d", mid->command, mid->mid); | ||
405 | if (mid->midState == MID_REQUEST_SUBMITTED) { | ||
406 | if (server->tcpStatus == CifsExiting) | ||
407 | rc = -EHOSTDOWN; | ||
408 | else { | ||
409 | server->tcpStatus = CifsNeedReconnect; | ||
410 | mid->midState = MID_RETRY_NEEDED; | ||
411 | } | ||
412 | } | ||
413 | |||
414 | if (rc != -EHOSTDOWN) { | ||
415 | if (mid->midState == MID_RETRY_NEEDED) { | ||
416 | rc = -EAGAIN; | ||
417 | cFYI(1, "marking request for retry"); | ||
418 | } else { | ||
419 | rc = -EIO; | ||
420 | } | ||
421 | } | ||
422 | spin_unlock(&GlobalMid_Lock); | ||
423 | |||
424 | delete_mid(mid); | ||
425 | return rc; | ||
426 | } | ||
427 | |||
392 | int | 428 | int |
393 | SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | 429 | SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, |
394 | struct kvec *iov, int n_vec, int *pRespBufType /* ret */, | 430 | struct kvec *iov, int n_vec, int *pRespBufType /* ret */, |
@@ -492,37 +528,13 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
492 | /* No user interrupts in wait - wreaks havoc with performance */ | 528 | /* No user interrupts in wait - wreaks havoc with performance */ |
493 | wait_for_response(ses, midQ, timeout, 10 * HZ); | 529 | wait_for_response(ses, midQ, timeout, 10 * HZ); |
494 | 530 | ||
495 | spin_lock(&GlobalMid_Lock); | 531 | rc = sync_mid_result(midQ, ses->server); |
496 | 532 | if (rc != 0) { | |
497 | if (midQ->resp_buf == NULL) { | ||
498 | cERROR(1, "No response to cmd %d mid %d", | ||
499 | midQ->command, midQ->mid); | ||
500 | if (midQ->midState == MID_REQUEST_SUBMITTED) { | ||
501 | if (ses->server->tcpStatus == CifsExiting) | ||
502 | rc = -EHOSTDOWN; | ||
503 | else { | ||
504 | ses->server->tcpStatus = CifsNeedReconnect; | ||
505 | midQ->midState = MID_RETRY_NEEDED; | ||
506 | } | ||
507 | } | ||
508 | |||
509 | if (rc != -EHOSTDOWN) { | ||
510 | if (midQ->midState == MID_RETRY_NEEDED) { | ||
511 | rc = -EAGAIN; | ||
512 | cFYI(1, "marking request for retry"); | ||
513 | } else { | ||
514 | rc = -EIO; | ||
515 | } | ||
516 | } | ||
517 | spin_unlock(&GlobalMid_Lock); | ||
518 | delete_mid(midQ); | ||
519 | /* Update # of requests on wire to server */ | ||
520 | atomic_dec(&ses->server->inFlight); | 533 | atomic_dec(&ses->server->inFlight); |
521 | wake_up(&ses->server->request_q); | 534 | wake_up(&ses->server->request_q); |
522 | return rc; | 535 | return rc; |
523 | } | 536 | } |
524 | 537 | ||
525 | spin_unlock(&GlobalMid_Lock); | ||
526 | receive_len = midQ->resp_buf->smb_buf_length; | 538 | receive_len = midQ->resp_buf->smb_buf_length; |
527 | 539 | ||
528 | if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { | 540 | if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { |
@@ -684,36 +696,13 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
684 | /* No user interrupts in wait - wreaks havoc with performance */ | 696 | /* No user interrupts in wait - wreaks havoc with performance */ |
685 | wait_for_response(ses, midQ, timeout, 10 * HZ); | 697 | wait_for_response(ses, midQ, timeout, 10 * HZ); |
686 | 698 | ||
687 | spin_lock(&GlobalMid_Lock); | 699 | rc = sync_mid_result(midQ, ses->server); |
688 | if (midQ->resp_buf == NULL) { | 700 | if (rc != 0) { |
689 | cERROR(1, "No response for cmd %d mid %d", | ||
690 | midQ->command, midQ->mid); | ||
691 | if (midQ->midState == MID_REQUEST_SUBMITTED) { | ||
692 | if (ses->server->tcpStatus == CifsExiting) | ||
693 | rc = -EHOSTDOWN; | ||
694 | else { | ||
695 | ses->server->tcpStatus = CifsNeedReconnect; | ||
696 | midQ->midState = MID_RETRY_NEEDED; | ||
697 | } | ||
698 | } | ||
699 | |||
700 | if (rc != -EHOSTDOWN) { | ||
701 | if (midQ->midState == MID_RETRY_NEEDED) { | ||
702 | rc = -EAGAIN; | ||
703 | cFYI(1, "marking request for retry"); | ||
704 | } else { | ||
705 | rc = -EIO; | ||
706 | } | ||
707 | } | ||
708 | spin_unlock(&GlobalMid_Lock); | ||
709 | delete_mid(midQ); | ||
710 | /* Update # of requests on wire to server */ | ||
711 | atomic_dec(&ses->server->inFlight); | 701 | atomic_dec(&ses->server->inFlight); |
712 | wake_up(&ses->server->request_q); | 702 | wake_up(&ses->server->request_q); |
713 | return rc; | 703 | return rc; |
714 | } | 704 | } |
715 | 705 | ||
716 | spin_unlock(&GlobalMid_Lock); | ||
717 | receive_len = midQ->resp_buf->smb_buf_length; | 706 | receive_len = midQ->resp_buf->smb_buf_length; |
718 | 707 | ||
719 | if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { | 708 | if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { |
@@ -933,35 +922,11 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, | |||
933 | } | 922 | } |
934 | } | 923 | } |
935 | 924 | ||
936 | spin_lock(&GlobalMid_Lock); | 925 | rc = sync_mid_result(midQ, ses->server); |
937 | if (midQ->resp_buf) { | 926 | if (rc != 0) |
938 | spin_unlock(&GlobalMid_Lock); | ||
939 | receive_len = midQ->resp_buf->smb_buf_length; | ||
940 | } else { | ||
941 | cERROR(1, "No response for cmd %d mid %d", | ||
942 | midQ->command, midQ->mid); | ||
943 | if (midQ->midState == MID_REQUEST_SUBMITTED) { | ||
944 | if (ses->server->tcpStatus == CifsExiting) | ||
945 | rc = -EHOSTDOWN; | ||
946 | else { | ||
947 | ses->server->tcpStatus = CifsNeedReconnect; | ||
948 | midQ->midState = MID_RETRY_NEEDED; | ||
949 | } | ||
950 | } | ||
951 | |||
952 | if (rc != -EHOSTDOWN) { | ||
953 | if (midQ->midState == MID_RETRY_NEEDED) { | ||
954 | rc = -EAGAIN; | ||
955 | cFYI(1, "marking request for retry"); | ||
956 | } else { | ||
957 | rc = -EIO; | ||
958 | } | ||
959 | } | ||
960 | spin_unlock(&GlobalMid_Lock); | ||
961 | delete_mid(midQ); | ||
962 | return rc; | 927 | return rc; |
963 | } | ||
964 | 928 | ||
929 | receive_len = midQ->resp_buf->smb_buf_length; | ||
965 | if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { | 930 | if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { |
966 | cERROR(1, "Frame too large received. Length: %d Xid: %d", | 931 | cERROR(1, "Frame too large received. Length: %d Xid: %d", |
967 | receive_len, xid); | 932 | receive_len, xid); |