Author: jra Date: 2006-07-15 21:10:27 +0000 (Sat, 15 Jul 2006) New Revision: 57
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=linux-cifs-client&rev=57 Log: Add in code to make timeouts absolute not relative. Jeremy. Modified: branches/linux-converged-for-old-kernels/fs/cifs/cifsglob.h branches/linux-converged-for-old-kernels/fs/cifs/connect.c branches/linux-converged-for-old-kernels/fs/cifs/transport.c Changeset: Modified: branches/linux-converged-for-old-kernels/fs/cifs/cifsglob.h =================================================================== --- branches/linux-converged-for-old-kernels/fs/cifs/cifsglob.h 2006-07-14 23:14:06 UTC (rev 56) +++ branches/linux-converged-for-old-kernels/fs/cifs/cifsglob.h 2006-07-15 21:10:27 UTC (rev 57) @@ -160,6 +160,7 @@ char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; __u32 sequence_number; /* needed for CIFS PDU signature */ char mac_signing_key[CIFS_SESS_KEY_SIZE + 16]; + unsigned long last_receive_time; }; /* Modified: branches/linux-converged-for-old-kernels/fs/cifs/connect.c =================================================================== --- branches/linux-converged-for-old-kernels/fs/cifs/connect.c 2006-07-14 23:14:06 UTC (rev 56) +++ branches/linux-converged-for-old-kernels/fs/cifs/connect.c 2006-07-15 21:10:27 UTC (rev 57) @@ -609,6 +609,10 @@ task_to_wake = NULL; spin_lock(&GlobalMid_Lock); + + /* Note when we last received a reply - needed for timeout purposes. */ + server->last_receive_time = jiffies; + list_for_each(tmp, &server->pending_mid_q) { mid_entry = list_entry(tmp, struct mid_q_entry, qhead); Modified: branches/linux-converged-for-old-kernels/fs/cifs/transport.c =================================================================== --- branches/linux-converged-for-old-kernels/fs/cifs/transport.c 2006-07-14 23:14:06 UTC (rev 56) +++ branches/linux-converged-for-old-kernels/fs/cifs/transport.c 2006-07-15 21:10:27 UTC (rev 57) @@ -3,7 +3,8 @@ * * Copyright (C) International Business Machines Corp., 2002,2005 * Author(s): Steve French ([EMAIL PROTECTED]) - * + * Jeremy Allison ([EMAIL PROTECTED]) 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 @@ -476,12 +477,40 @@ /* 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) || - ((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->last_receive_time; + spin_unlock(&GlobalMid_Lock); + + /* Calculate 15 seconds past last received time. */ + lrt += (15 * HZ); + if (time_after(jiffies, lrt)) { + /* Server sent no replies for 15 seconds. */ + cERROR(1,("Server idle for 15 seconds. Timing out")); + break; + } + } else { + break; + } + } } else { wait_event(ses->server->response_q, (!(midQ->midState & MID_REQUEST_SUBMITTED)) || @@ -743,12 +772,40 @@ /* 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) || - ((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->last_receive_time; + spin_unlock(&GlobalMid_Lock); + + /* Calculate 15 seconds past last received time. */ + lrt += (15 * HZ); + if (time_after(jiffies, lrt)) { + /* Server sent no replies for 15 seconds. */ + cERROR(1,("Server idle for 15 seconds. Timing out")); + break; + } + } else { + break; + } + } } else { wait_event(ses->server->response_q, (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||