[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)

+76 -23
+76 -23
fs/cifs/transport.c
··· 3 3 * 4 4 * Copyright (C) International Business Machines Corp., 2002,2005 5 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 - * 6 + * Jeremy Allison (jra@samba.org) 2006. 7 + * 7 8 * This library is free software; you can redistribute it and/or modify 8 9 * it under the terms of the GNU Lesser General Public License as published 9 10 * by the Free Software Foundation; either version 2.1 of the License, or ··· 443 442 444 443 /* No user interrupts in wait - wreaks havoc with performance */ 445 444 if(timeout != MAX_SCHEDULE_TIMEOUT) { 446 - timeout += jiffies; 447 - wait_event(ses->server->response_q, 448 - (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 449 - (time_after(jiffies, timeout) && 450 - time_after(jiffies, ses->server->lstrp + HZ)) || 451 - ((ses->server->tcpStatus != CifsGood) && 452 - (ses->server->tcpStatus != CifsNew))); 445 + unsigned long curr_timeout; 446 + 447 + for (;;) { 448 + curr_timeout = timeout + jiffies; 449 + wait_event(ses->server->response_q, 450 + (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 451 + time_after(jiffies, curr_timeout) || 452 + ((ses->server->tcpStatus != CifsGood) && 453 + (ses->server->tcpStatus != CifsNew))); 454 + 455 + if (time_after(jiffies, curr_timeout) && 456 + (midQ->midState & MID_REQUEST_SUBMITTED) && 457 + ((ses->server->tcpStatus == CifsGood) || 458 + (ses->server->tcpStatus == CifsNew))) { 459 + 460 + unsigned long lrt; 461 + 462 + /* We timed out. Is the server still 463 + sending replies ? */ 464 + spin_lock(&GlobalMid_Lock); 465 + lrt = ses->server->lstrp; 466 + spin_unlock(&GlobalMid_Lock); 467 + 468 + /* Calculate 10 seconds past last receive time. 469 + Although we prefer not to time out if the 470 + server is still responding - we will time 471 + out if the server takes more than 15 (or 45 472 + or 180) seconds to respond to this request 473 + and has not responded to any request from 474 + other threads on the client within 10 seconds */ 475 + lrt += (10 * HZ); 476 + if (time_after(jiffies, lrt)) { 477 + /* No replies for 10 seconds. */ 478 + cERROR(1,("server not responding")); 479 + break; 480 + } 481 + } else { 482 + break; 483 + } 484 + } 453 485 } else { 454 486 wait_event(ses->server->response_q, 455 487 (!(midQ->midState & MID_REQUEST_SUBMITTED)) || ··· 744 710 745 711 /* No user interrupts in wait - wreaks havoc with performance */ 746 712 if(timeout != MAX_SCHEDULE_TIMEOUT) { 747 - timeout += jiffies; 748 - /* although we prefer not to time out if the server is still 749 - responding - we will time out if the server takes 750 - more than 15 (or 45 or 180) seconds to respond to this request 751 - and has not responded to any request from other threads 752 - on this client within a second (note that it is not worth 753 - grabbing the GlobalMid_Lock and slowing things down in this 754 - wait event to more accurately check the lstrsp field on some 755 - arch since we are already in an error path that will retry */ 756 - wait_event(ses->server->response_q, 757 - (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 758 - (time_after(jiffies, timeout) && 759 - time_after(jiffies, ses->server->lstrp + HZ)) || 760 - ((ses->server->tcpStatus != CifsGood) && 761 - (ses->server->tcpStatus != CifsNew))); 713 + unsigned long curr_timeout; 714 + 715 + for (;;) { 716 + curr_timeout = timeout + jiffies; 717 + wait_event(ses->server->response_q, 718 + (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 719 + time_after(jiffies, curr_timeout) || 720 + ((ses->server->tcpStatus != CifsGood) && 721 + (ses->server->tcpStatus != CifsNew))); 722 + 723 + if (time_after(jiffies, curr_timeout) && 724 + (midQ->midState & MID_REQUEST_SUBMITTED) && 725 + ((ses->server->tcpStatus == CifsGood) || 726 + (ses->server->tcpStatus == CifsNew))) { 727 + 728 + unsigned long lrt; 729 + 730 + /* We timed out. Is the server still 731 + sending replies ? */ 732 + spin_lock(&GlobalMid_Lock); 733 + lrt = ses->server->lstrp; 734 + spin_unlock(&GlobalMid_Lock); 735 + 736 + /* Calculate 10 seconds past last receive time*/ 737 + lrt += (10 * HZ); 738 + if (time_after(jiffies, lrt)) { 739 + /* Server sent no reply in 10 seconds */ 740 + cERROR(1,("Server not responding")); 741 + break; 742 + } 743 + } else { 744 + break; 745 + } 746 + } 762 747 } else { 763 748 wait_event(ses->server->response_q, 764 749 (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||