[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:
@@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) International Business Machines Corp., 2002,2005
|
* Copyright (C) International Business Machines Corp., 2002,2005
|
||||||
* Author(s): Steve French (sfrench@us.ibm.com)
|
* 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
|
* 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
|
* 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
|
* 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 */
|
/* No user interrupts in wait - wreaks havoc with performance */
|
||||||
if(timeout != MAX_SCHEDULE_TIMEOUT) {
|
if(timeout != MAX_SCHEDULE_TIMEOUT) {
|
||||||
timeout += jiffies;
|
unsigned long curr_timeout;
|
||||||
wait_event(ses->server->response_q,
|
|
||||||
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
|
for (;;) {
|
||||||
(time_after(jiffies, timeout) &&
|
curr_timeout = timeout + jiffies;
|
||||||
time_after(jiffies, ses->server->lstrp + HZ)) ||
|
wait_event(ses->server->response_q,
|
||||||
((ses->server->tcpStatus != CifsGood) &&
|
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
|
||||||
(ses->server->tcpStatus != CifsNew)));
|
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 {
|
} else {
|
||||||
wait_event(ses->server->response_q,
|
wait_event(ses->server->response_q,
|
||||||
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
|
(!(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 */
|
/* No user interrupts in wait - wreaks havoc with performance */
|
||||||
if(timeout != MAX_SCHEDULE_TIMEOUT) {
|
if(timeout != MAX_SCHEDULE_TIMEOUT) {
|
||||||
timeout += jiffies;
|
unsigned long curr_timeout;
|
||||||
/* although we prefer not to time out if the server is still
|
|
||||||
responding - we will time out if the server takes
|
for (;;) {
|
||||||
more than 15 (or 45 or 180) seconds to respond to this request
|
curr_timeout = timeout + jiffies;
|
||||||
and has not responded to any request from other threads
|
wait_event(ses->server->response_q,
|
||||||
on this client within a second (note that it is not worth
|
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
|
||||||
grabbing the GlobalMid_Lock and slowing things down in this
|
time_after(jiffies, curr_timeout) ||
|
||||||
wait event to more accurately check the lstrsp field on some
|
((ses->server->tcpStatus != CifsGood) &&
|
||||||
arch since we are already in an error path that will retry */
|
(ses->server->tcpStatus != CifsNew)));
|
||||||
wait_event(ses->server->response_q,
|
|
||||||
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
|
if (time_after(jiffies, curr_timeout) &&
|
||||||
(time_after(jiffies, timeout) &&
|
(midQ->midState & MID_REQUEST_SUBMITTED) &&
|
||||||
time_after(jiffies, ses->server->lstrp + HZ)) ||
|
((ses->server->tcpStatus == CifsGood) ||
|
||||||
((ses->server->tcpStatus != CifsGood) &&
|
(ses->server->tcpStatus == CifsNew))) {
|
||||||
(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 {
|
} else {
|
||||||
wait_event(ses->server->response_q,
|
wait_event(ses->server->response_q,
|
||||||
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
|
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
|
||||||
|
Reference in New Issue
Block a user