forked from Minki/linux
[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)
This commit is contained in:
parent
3a5ff61c18
commit
14a441a2b4
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright (C) International Business Machines Corp., 2002,2005
|
||||
* Author(s): Steve French (sfrench@us.ibm.com)
|
||||
* Jeremy Allison (jra@samba.org) 2006.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published
|
||||
@ -442,13 +443,46 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
|
||||
|
||||
/* No user interrupts in wait - wreaks havoc with performance */
|
||||
if(timeout != MAX_SCHEDULE_TIMEOUT) {
|
||||
timeout += jiffies;
|
||||
unsigned long curr_timeout;
|
||||
|
||||
for (;;) {
|
||||
curr_timeout = timeout + jiffies;
|
||||
wait_event(ses->server->response_q,
|
||||
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
|
||||
(time_after(jiffies, timeout) &&
|
||||
time_after(jiffies, ses->server->lstrp + HZ)) ||
|
||||
time_after(jiffies, curr_timeout) ||
|
||||
((ses->server->tcpStatus != CifsGood) &&
|
||||
(ses->server->tcpStatus != CifsNew)));
|
||||
|
||||
if (time_after(jiffies, curr_timeout) &&
|
||||
(midQ->midState & MID_REQUEST_SUBMITTED) &&
|
||||
((ses->server->tcpStatus == CifsGood) ||
|
||||
(ses->server->tcpStatus == CifsNew))) {
|
||||
|
||||
unsigned long lrt;
|
||||
|
||||
/* We timed out. Is the server still
|
||||
sending replies ? */
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
lrt = ses->server->lstrp;
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
|
||||
/* Calculate 10 seconds past last receive time.
|
||||
Although we prefer not to time out if the
|
||||
server is still responding - we will time
|
||||
out if the server takes more than 15 (or 45
|
||||
or 180) seconds to respond to this request
|
||||
and has not responded to any request from
|
||||
other threads on the client within 10 seconds */
|
||||
lrt += (10 * HZ);
|
||||
if (time_after(jiffies, lrt)) {
|
||||
/* No replies for 10 seconds. */
|
||||
cERROR(1,("server not responding"));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wait_event(ses->server->response_q,
|
||||
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
|
||||
@ -710,21 +744,40 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
|
||||
|
||||
/* No user interrupts in wait - wreaks havoc with performance */
|
||||
if(timeout != MAX_SCHEDULE_TIMEOUT) {
|
||||
timeout += jiffies;
|
||||
/* although we prefer not to time out if the server is still
|
||||
responding - we will time out if the server takes
|
||||
more than 15 (or 45 or 180) seconds to respond to this request
|
||||
and has not responded to any request from other threads
|
||||
on this client within a second (note that it is not worth
|
||||
grabbing the GlobalMid_Lock and slowing things down in this
|
||||
wait event to more accurately check the lstrsp field on some
|
||||
arch since we are already in an error path that will retry */
|
||||
unsigned long curr_timeout;
|
||||
|
||||
for (;;) {
|
||||
curr_timeout = timeout + jiffies;
|
||||
wait_event(ses->server->response_q,
|
||||
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
|
||||
(time_after(jiffies, timeout) &&
|
||||
time_after(jiffies, ses->server->lstrp + HZ)) ||
|
||||
time_after(jiffies, curr_timeout) ||
|
||||
((ses->server->tcpStatus != CifsGood) &&
|
||||
(ses->server->tcpStatus != CifsNew)));
|
||||
|
||||
if (time_after(jiffies, curr_timeout) &&
|
||||
(midQ->midState & MID_REQUEST_SUBMITTED) &&
|
||||
((ses->server->tcpStatus == CifsGood) ||
|
||||
(ses->server->tcpStatus == CifsNew))) {
|
||||
|
||||
unsigned long lrt;
|
||||
|
||||
/* We timed out. Is the server still
|
||||
sending replies ? */
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
lrt = ses->server->lstrp;
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
|
||||
/* Calculate 10 seconds past last receive time*/
|
||||
lrt += (10 * HZ);
|
||||
if (time_after(jiffies, lrt)) {
|
||||
/* Server sent no reply in 10 seconds */
|
||||
cERROR(1,("Server not responding"));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wait_event(ses->server->response_q,
|
||||
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
|
||||
|
Loading…
Reference in New Issue
Block a user