[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)
···33 *44 * Copyright (C) International Business Machines Corp., 2002,200555 * Author(s): Steve French (sfrench@us.ibm.com)66- *66+ * Jeremy Allison (jra@samba.org) 2006.77+ * 78 * This library is free software; you can redistribute it and/or modify89 * it under the terms of the GNU Lesser General Public License as published910 * by the Free Software Foundation; either version 2.1 of the License, or···443442444443 /* No user interrupts in wait - wreaks havoc with performance */445444 if(timeout != MAX_SCHEDULE_TIMEOUT) {446446- timeout += jiffies;447447- wait_event(ses->server->response_q,448448- (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||449449- (time_after(jiffies, timeout) &&450450- time_after(jiffies, ses->server->lstrp + HZ)) ||451451- ((ses->server->tcpStatus != CifsGood) &&452452- (ses->server->tcpStatus != CifsNew)));445445+ unsigned long curr_timeout;446446+447447+ for (;;) {448448+ curr_timeout = timeout + jiffies;449449+ wait_event(ses->server->response_q,450450+ (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 451451+ time_after(jiffies, curr_timeout) || 452452+ ((ses->server->tcpStatus != CifsGood) &&453453+ (ses->server->tcpStatus != CifsNew)));454454+455455+ if (time_after(jiffies, curr_timeout) &&456456+ (midQ->midState & MID_REQUEST_SUBMITTED) &&457457+ ((ses->server->tcpStatus == CifsGood) ||458458+ (ses->server->tcpStatus == CifsNew))) {459459+460460+ unsigned long lrt;461461+462462+ /* We timed out. Is the server still463463+ sending replies ? */464464+ spin_lock(&GlobalMid_Lock);465465+ lrt = ses->server->lstrp;466466+ spin_unlock(&GlobalMid_Lock);467467+468468+ /* Calculate 10 seconds past last receive time.469469+ Although we prefer not to time out if the 470470+ server is still responding - we will time471471+ out if the server takes more than 15 (or 45 472472+ or 180) seconds to respond to this request473473+ and has not responded to any request from 474474+ other threads on the client within 10 seconds */475475+ lrt += (10 * HZ);476476+ if (time_after(jiffies, lrt)) {477477+ /* No replies for 10 seconds. */478478+ cERROR(1,("server not responding"));479479+ break;480480+ }481481+ } else {482482+ break;483483+ }484484+ }453485 } else {454486 wait_event(ses->server->response_q,455487 (!(midQ->midState & MID_REQUEST_SUBMITTED)) || ···744710745711 /* No user interrupts in wait - wreaks havoc with performance */746712 if(timeout != MAX_SCHEDULE_TIMEOUT) {747747- timeout += jiffies;748748- /* although we prefer not to time out if the server is still749749- responding - we will time out if the server takes750750- more than 15 (or 45 or 180) seconds to respond to this request751751- and has not responded to any request from other threads752752- on this client within a second (note that it is not worth753753- grabbing the GlobalMid_Lock and slowing things down in this754754- wait event to more accurately check the lstrsp field on some 755755- arch since we are already in an error path that will retry */756756- wait_event(ses->server->response_q,757757- (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 758758- (time_after(jiffies, timeout) &&759759- time_after(jiffies, ses->server->lstrp + HZ)) ||760760- ((ses->server->tcpStatus != CifsGood) &&761761- (ses->server->tcpStatus != CifsNew)));713713+ unsigned long curr_timeout;714714+715715+ for (;;) {716716+ curr_timeout = timeout + jiffies;717717+ wait_event(ses->server->response_q,718718+ (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 719719+ time_after(jiffies, curr_timeout) || 720720+ ((ses->server->tcpStatus != CifsGood) &&721721+ (ses->server->tcpStatus != CifsNew)));722722+723723+ if (time_after(jiffies, curr_timeout) &&724724+ (midQ->midState & MID_REQUEST_SUBMITTED) &&725725+ ((ses->server->tcpStatus == CifsGood) ||726726+ (ses->server->tcpStatus == CifsNew))) {727727+728728+ unsigned long lrt;729729+730730+ /* We timed out. Is the server still731731+ sending replies ? */732732+ spin_lock(&GlobalMid_Lock);733733+ lrt = ses->server->lstrp;734734+ spin_unlock(&GlobalMid_Lock);735735+736736+ /* Calculate 10 seconds past last receive time*/737737+ lrt += (10 * HZ);738738+ if (time_after(jiffies, lrt)) {739739+ /* Server sent no reply in 10 seconds */740740+ cERROR(1,("Server not responding"));741741+ break;742742+ }743743+ } else {744744+ break;745745+ }746746+ }762747 } else {763748 wait_event(ses->server->response_q,764749 (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||