]> err.no Git - linux-2.6/blobdiff - fs/cifs/transport.c
[CIFS] Do not time out posix brl requests when using new posix setfileinfo
[linux-2.6] / fs / cifs / transport.c
index 7b98792150ea7ebba3d449e994906483dcadf4a3..95e23ca670a8002ab3656cbc46423051d05ffbf2 100644 (file)
@@ -309,17 +309,16 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        
        *pRespBufType = CIFS_NO_BUFFER;  /* no response buf yet */
 
-       if (ses == NULL) {
-               cERROR(1,("Null smb session"));
-               return -EIO;
-       }
-       if(ses->server == NULL) {
-               cERROR(1,("Null tcp session"));
+       if ((ses == NULL) || (ses->server == NULL)) {
+               cifs_small_buf_release(in_buf);
+               cERROR(1,("Null session"));
                return -EIO;
        }
 
-       if(ses->server->tcpStatus == CifsExiting)
+       if(ses->server->tcpStatus == CifsExiting) {
+               cifs_small_buf_release(in_buf);
                return -ENOENT;
+       }
 
        /* Ensure that we do not send more than 50 overlapping requests 
           to the same server. We may make this configurable later or
@@ -346,6 +345,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                        } else {
                                if(ses->server->tcpStatus == CifsExiting) {
                                        spin_unlock(&GlobalMid_Lock);
+                                       cifs_small_buf_release(in_buf);
                                        return -ENOENT;
                                }
 
@@ -385,6 +385,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        midQ = AllocMidQEntry(in_buf, ses);
        if (midQ == NULL) {
                up(&ses->server->tcpSem);
+               cifs_small_buf_release(in_buf);
                /* If not lock req, update # of requests on wire to server */
                if(long_op < 3) {
                        atomic_dec(&ses->server->inFlight); 
@@ -408,14 +409,18 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        if(rc < 0) {
                DeleteMidQEntry(midQ);
                up(&ses->server->tcpSem);
+               cifs_small_buf_release(in_buf);
                /* If not lock req, update # of requests on wire to server */
                if(long_op < 3) {
                        atomic_dec(&ses->server->inFlight); 
                        wake_up(&ses->server->request_q);
                }
                return rc;
-       } else
+       } else {
                up(&ses->server->tcpSem);
+               cifs_small_buf_release(in_buf);
+       }
+
        if (long_op == -1)
                goto cifs_no_response_exit2;
        else if (long_op == 2) /* writes past end of file can take loong time */
@@ -439,8 +444,9 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        if(timeout != MAX_SCHEDULE_TIMEOUT) {
                timeout += jiffies;
                wait_event(ses->server->response_q,
-                       (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
-                       time_after(jiffies, timeout) || 
+                       (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
+                       (time_after(jiffies, timeout) &&
+                               time_after(jiffies, ses->server->lstrp + HZ)) ||
                        ((ses->server->tcpStatus != CifsGood) &&
                         (ses->server->tcpStatus != CifsNew)));
        } else {
@@ -498,7 +504,6 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                        else
                                *pRespBufType = CIFS_SMALL_BUFFER;
                        iov[0].iov_len = receive_len + 4;
-                       iov[1].iov_len = 0;
 
                        dump_smb(midQ->resp_buf, 80);
                        /* convert the length into a more usable form */
@@ -544,6 +549,7 @@ cifs_no_response_exit2:
 
 out_unlock2:
        up(&ses->server->tcpSem);
+       cifs_small_buf_release(in_buf);
        /* If not lock req, update # of requests on wire to server */
        if(long_op < 3) {
                atomic_dec(&ses->server->inFlight); 
@@ -649,8 +655,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
 
        if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
                up(&ses->server->tcpSem);
-               cERROR(1,
-                      ("Illegal length, greater than maximum frame, %d ",
+               cERROR(1, ("Illegal length, greater than maximum frame, %d",
                        in_buf->smb_buf_length));
                DeleteMidQEntry(midQ);
                /* If not lock req, update # of requests on wire to server */
@@ -706,9 +711,18 @@ 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, timeout) &&
+                               time_after(jiffies, ses->server->lstrp + HZ)) ||
                        ((ses->server->tcpStatus != CifsGood) &&
                         (ses->server->tcpStatus != CifsNew)));
        } else {