aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/transport.c121
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
392static int
393sync_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
392int 428int
393SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 429SendReceive2(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);