[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:
Steve French 2006-07-16 04:32:51 +00:00
parent 3a5ff61c18
commit 14a441a2b4
1 changed files with 76 additions and 23 deletions

View File

@ -3,7 +3,8 @@
*
* 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
* 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,
/* No user interrupts in wait - wreaks havoc with performance */
if(timeout != MAX_SCHEDULE_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)) ||
((ses->server->tcpStatus != CifsGood) &&
(ses->server->tcpStatus != CifsNew)));
unsigned long curr_timeout;
for (;;) {
curr_timeout = timeout + jiffies;
wait_event(ses->server->response_q,
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
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 */
wait_event(ses->server->response_q,
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
(time_after(jiffies, timeout) &&
time_after(jiffies, ses->server->lstrp + HZ)) ||
((ses->server->tcpStatus != CifsGood) &&
(ses->server->tcpStatus != CifsNew)));
unsigned long curr_timeout;
for (;;) {
curr_timeout = timeout + jiffies;
wait_event(ses->server->response_q,
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
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)) ||