diff options
author | Steve French <sfrench@us.ibm.com> | 2006-07-16 00:32:51 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-08-11 17:27:41 -0400 |
commit | 14a441a2b4ee1dfc00ec822d91d9fb20f401c62f (patch) | |
tree | 122a33e5e056bdd433e78b4f6a1c9f8e2d3385d2 /fs | |
parent | 3a5ff61c18659443f76bad6cf06f60103046de5d (diff) |
[CIFS] spinlock protect read of last srv response time in timeout path
Signed-off-by: Jeremy Allison <jra@samba.org>
Signed-off-by: Steve French <sfrench@us.ibm.com>
(cherry picked from b33a3f55e54fd210fc043eafcf83728b03bc9e02 commit)
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/transport.c | 99 |
1 files changed, 76 insertions, 23 deletions
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 95e23ca670a8..d16e6032d4cf 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -3,7 +3,8 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2005 | 4 | * Copyright (C) International Business Machines Corp., 2002,2005 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * Jeremy Allison (jra@samba.org) 2006. |
7 | * | ||
7 | * This library is free software; you can redistribute it and/or modify | 8 | * This library is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU Lesser General Public License as published | 9 | * it under the terms of the GNU Lesser General Public License as published |
9 | * by the Free Software Foundation; either version 2.1 of the License, or | 10 | * by the Free Software Foundation; either version 2.1 of the License, or |
@@ -442,13 +443,46 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
442 | 443 | ||
443 | /* No user interrupts in wait - wreaks havoc with performance */ | 444 | /* No user interrupts in wait - wreaks havoc with performance */ |
444 | if(timeout != MAX_SCHEDULE_TIMEOUT) { | 445 | if(timeout != MAX_SCHEDULE_TIMEOUT) { |
445 | timeout += jiffies; | 446 | unsigned long curr_timeout; |
446 | wait_event(ses->server->response_q, | 447 | |
447 | (!(midQ->midState & MID_REQUEST_SUBMITTED)) || | 448 | for (;;) { |
448 | (time_after(jiffies, timeout) && | 449 | curr_timeout = timeout + jiffies; |
449 | time_after(jiffies, ses->server->lstrp + HZ)) || | 450 | wait_event(ses->server->response_q, |
450 | ((ses->server->tcpStatus != CifsGood) && | 451 | (!(midQ->midState & MID_REQUEST_SUBMITTED)) || |
451 | (ses->server->tcpStatus != CifsNew))); | 452 | time_after(jiffies, curr_timeout) || |
453 | ((ses->server->tcpStatus != CifsGood) && | ||
454 | (ses->server->tcpStatus != CifsNew))); | ||
455 | |||
456 | if (time_after(jiffies, curr_timeout) && | ||
457 | (midQ->midState & MID_REQUEST_SUBMITTED) && | ||
458 | ((ses->server->tcpStatus == CifsGood) || | ||
459 | (ses->server->tcpStatus == CifsNew))) { | ||
460 | |||
461 | unsigned long lrt; | ||
462 | |||
463 | /* We timed out. Is the server still | ||
464 | sending replies ? */ | ||
465 | spin_lock(&GlobalMid_Lock); | ||
466 | lrt = ses->server->lstrp; | ||
467 | spin_unlock(&GlobalMid_Lock); | ||
468 | |||
469 | /* Calculate 10 seconds past last receive time. | ||
470 | Although we prefer not to time out if the | ||
471 | server is still responding - we will time | ||
472 | out if the server takes more than 15 (or 45 | ||
473 | or 180) seconds to respond to this request | ||
474 | and has not responded to any request from | ||
475 | other threads on the client within 10 seconds */ | ||
476 | lrt += (10 * HZ); | ||
477 | if (time_after(jiffies, lrt)) { | ||
478 | /* No replies for 10 seconds. */ | ||
479 | cERROR(1,("server not responding")); | ||
480 | break; | ||
481 | } | ||
482 | } else { | ||
483 | break; | ||
484 | } | ||
485 | } | ||
452 | } else { | 486 | } else { |
453 | wait_event(ses->server->response_q, | 487 | wait_event(ses->server->response_q, |
454 | (!(midQ->midState & MID_REQUEST_SUBMITTED)) || | 488 | (!(midQ->midState & MID_REQUEST_SUBMITTED)) || |
@@ -710,21 +744,40 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
710 | 744 | ||
711 | /* No user interrupts in wait - wreaks havoc with performance */ | 745 | /* No user interrupts in wait - wreaks havoc with performance */ |
712 | if(timeout != MAX_SCHEDULE_TIMEOUT) { | 746 | if(timeout != MAX_SCHEDULE_TIMEOUT) { |
713 | timeout += jiffies; | 747 | unsigned long curr_timeout; |
714 | /* although we prefer not to time out if the server is still | 748 | |
715 | responding - we will time out if the server takes | 749 | for (;;) { |
716 | more than 15 (or 45 or 180) seconds to respond to this request | 750 | curr_timeout = timeout + jiffies; |
717 | and has not responded to any request from other threads | 751 | wait_event(ses->server->response_q, |
718 | on this client within a second (note that it is not worth | 752 | (!(midQ->midState & MID_REQUEST_SUBMITTED)) || |
719 | grabbing the GlobalMid_Lock and slowing things down in this | 753 | time_after(jiffies, curr_timeout) || |
720 | wait event to more accurately check the lstrsp field on some | 754 | ((ses->server->tcpStatus != CifsGood) && |
721 | arch since we are already in an error path that will retry */ | 755 | (ses->server->tcpStatus != CifsNew))); |
722 | wait_event(ses->server->response_q, | 756 | |
723 | (!(midQ->midState & MID_REQUEST_SUBMITTED)) || | 757 | if (time_after(jiffies, curr_timeout) && |
724 | (time_after(jiffies, timeout) && | 758 | (midQ->midState & MID_REQUEST_SUBMITTED) && |
725 | time_after(jiffies, ses->server->lstrp + HZ)) || | 759 | ((ses->server->tcpStatus == CifsGood) || |
726 | ((ses->server->tcpStatus != CifsGood) && | 760 | (ses->server->tcpStatus == CifsNew))) { |
727 | (ses->server->tcpStatus != CifsNew))); | 761 | |
762 | unsigned long lrt; | ||
763 | |||
764 | /* We timed out. Is the server still | ||
765 | sending replies ? */ | ||
766 | spin_lock(&GlobalMid_Lock); | ||
767 | lrt = ses->server->lstrp; | ||
768 | spin_unlock(&GlobalMid_Lock); | ||
769 | |||
770 | /* Calculate 10 seconds past last receive time*/ | ||
771 | lrt += (10 * HZ); | ||
772 | if (time_after(jiffies, lrt)) { | ||
773 | /* Server sent no reply in 10 seconds */ | ||
774 | cERROR(1,("Server not responding")); | ||
775 | break; | ||
776 | } | ||
777 | } else { | ||
778 | break; | ||
779 | } | ||
780 | } | ||
728 | } else { | 781 | } else { |
729 | wait_event(ses->server->response_q, | 782 | wait_event(ses->server->response_q, |
730 | (!(midQ->midState & MID_REQUEST_SUBMITTED)) || | 783 | (!(midQ->midState & MID_REQUEST_SUBMITTED)) || |