linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / fs / cifs / transport.c
index 48d47b4..b12cb8a 100644 (file)
@@ -3,8 +3,7 @@
  *
  *   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
@@ -37,7 +36,7 @@ extern mempool_t *cifs_mid_poolp;
 extern kmem_cache_t *cifs_oplock_cachep;
 
 static struct mid_q_entry *
-AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
+AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
 {
        struct mid_q_entry *temp;
 
@@ -204,10 +203,6 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
                rc = 0;
        }
 
-       /* Don't want to modify the buffer as a
-          side effect of this call. */
-       smb_buffer->smb_buf_length = smb_buf_length;
-
        return rc;
 }
 
@@ -222,7 +217,6 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
        unsigned int len = iov[0].iov_len;
        unsigned int total_len;
        int first_vec = 0;
-       unsigned int smb_buf_length = smb_buffer->smb_buf_length;
        
        if(ssocket == NULL)
                return -ENOTSOCK; /* BB eventually add reconnect code here */
@@ -299,15 +293,37 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
        } else
                rc = 0;
 
-       /* Don't want to modify the buffer as a
-          side effect of this call. */
-       smb_buffer->smb_buf_length = smb_buf_length;
-
        return rc;
 }
 
-static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
+int
+SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 
+            struct kvec *iov, int n_vec, int * pRespBufType /* ret */, 
+            const int long_op)
 {
+       int rc = 0;
+       unsigned int receive_len;
+       unsigned long timeout;
+       struct mid_q_entry *midQ;
+       struct smb_hdr *in_buf = iov[0].iov_base;
+       
+       *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"));
+               return -EIO;
+       }
+
+       if(ses->server->tcpStatus == CifsExiting)
+               return -ENOENT;
+
+       /* Ensure that we do not send more than 50 overlapping requests 
+          to the same server. We may make this configurable later or
+          use ses->maxReq */
        if(long_op == -1) {
                /* oplock breaks must not be held up */
                atomic_inc(&ses->server->inFlight);
@@ -333,137 +349,48 @@ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
                                        return -ENOENT;
                                }
 
-                               /* can not count locking commands against total since
-                                  they are allowed to block on server */
+                       /* can not count locking commands against total since
+                          they are allowed to block on server */
                                        
+                               if(long_op < 3) {
                                /* update # of requests on the wire to server */
-                               if (long_op < 3)
                                        atomic_inc(&ses->server->inFlight);
+                               }
                                spin_unlock(&GlobalMid_Lock);
                                break;
                        }
                }
        }
-       return 0;
-}
+       /* make sure that we sign in the same order that we send on this socket 
+          and avoid races inside tcp sendmsg code that could cause corruption
+          of smb data */
+
+       down(&ses->server->tcpSem); 
 
-static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
-                       struct mid_q_entry **ppmidQ)
-{
        if (ses->server->tcpStatus == CifsExiting) {
-               return -ENOENT;
+               rc = -ENOENT;
+               goto out_unlock2;
        } else if (ses->server->tcpStatus == CifsNeedReconnect) {
                cFYI(1,("tcp session dead - return to caller to retry"));
-               return -EAGAIN;
+               rc = -EAGAIN;
+               goto out_unlock2;
        } else if (ses->status != CifsGood) {
                /* check if SMB session is bad because we are setting it up */
                if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 
                        (in_buf->Command != SMB_COM_NEGOTIATE)) {
-                       return -EAGAIN;
+                       rc = -EAGAIN;
+                       goto out_unlock2;
                } /* else ok - we are setting up session */
        }
-       *ppmidQ = AllocMidQEntry(in_buf, ses);
-       if (*ppmidQ == NULL) {
-               return -ENOMEM;
-       }
-       return 0;
-}
-
-static int wait_for_response(struct cifsSesInfo *ses, 
-                       struct mid_q_entry *midQ,
-                       unsigned long timeout,
-                       unsigned long time_to_wait)
-{
-       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 time_to_wait 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 += time_to_wait;
-                       if (time_after(jiffies, lrt)) {
-                               /* No replies for time_to_wait. */
-                               cERROR(1,("server not responding"));
-                               return -1;
-                       }
-               } else {
-                       return 0;
-               }
-       }
-}
-
-int
-SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 
-            struct kvec *iov, int n_vec, int * pRespBufType /* ret */, 
-            const int long_op)
-{
-       int rc = 0;
-       unsigned int receive_len;
-       unsigned long timeout;
-       struct mid_q_entry *midQ;
-       struct smb_hdr *in_buf = iov[0].iov_base;
-       
-       *pRespBufType = CIFS_NO_BUFFER;  /* no response buf yet */
-
-       if ((ses == NULL) || (ses->server == NULL)) {
-               cifs_small_buf_release(in_buf);
-               cERROR(1,("Null session"));
-               return -EIO;
-       }
-
-       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
-          use ses->maxReq */
-
-       rc = wait_for_free_request(ses, long_op);
-       if (rc) {
-               cifs_small_buf_release(in_buf);
-               return rc;
-       }
-
-       /* make sure that we sign in the same order that we send on this socket 
-          and avoid races inside tcp sendmsg code that could cause corruption
-          of smb data */
-
-       down(&ses->server->tcpSem); 
-
-       rc = allocate_mid(ses, in_buf, &midQ);
-       if (rc) {
+       midQ = AllocMidQEntry(in_buf, ses);
+       if (midQ == NULL) {
                up(&ses->server->tcpSem);
-               cifs_small_buf_release(in_buf);
-               /* Update # of requests on wire to server */
-               atomic_dec(&ses->server->inFlight); 
-               wake_up(&ses->server->request_q);
-               return rc;
+               /* 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 -ENOMEM;
        }
 
        rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
@@ -478,23 +405,28 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        atomic_dec(&ses->server->inSend);
        midQ->when_sent = jiffies;
 #endif
-
-       up(&ses->server->tcpSem);
-       cifs_small_buf_release(in_buf);
-
-       if(rc < 0)
-               goto out;
-
+       if(rc < 0) {
+               DeleteMidQEntry(midQ);
+               up(&ses->server->tcpSem);
+               /* 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
+               up(&ses->server->tcpSem);
        if (long_op == -1)
-               goto out;
+               goto cifs_no_response_exit2;
        else if (long_op == 2) /* writes past end of file can take loong time */
                timeout = 180 * HZ;
        else if (long_op == 1)
                timeout = 45 * HZ; /* should be greater than 
                        servers oplock break timeout (about 43 seconds) */
-       else
+       else if (long_op > 2) {
+               timeout = MAX_SCHEDULE_TIMEOUT;
+       } else
                timeout = 15 * HZ;
-
        /* wait for 15 seconds or until woken up due to response arriving or 
           due to last connection to this server being unmounted */
        if (signal_pending(current)) {
@@ -504,7 +436,19 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        }   
 
        /* No user interrupts in wait - wreaks havoc with performance */
-       wait_for_response(ses, midQ, timeout, 10 * HZ);
+       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)));
+       } else {
+               wait_event(ses->server->response_q,
+                       (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
+                       ((ses->server->tcpStatus != CifsGood) &&
+                        (ses->server->tcpStatus != CifsNew)));
+       }
 
        spin_lock(&GlobalMid_Lock);
        if (midQ->resp_buf) {
@@ -532,9 +476,11 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                }
                spin_unlock(&GlobalMid_Lock);
                DeleteMidQEntry(midQ);
-               /* Update # of requests on wire to server */
-               atomic_dec(&ses->server->inFlight); 
-               wake_up(&ses->server->request_q);
+               /* 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;
        }
   
@@ -585,12 +531,23 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                        cFYI(1,("Bad MID state?"));
                }
        }
+cifs_no_response_exit2:
+       DeleteMidQEntry(midQ);
 
-out:
+       if(long_op < 3) {
+               atomic_dec(&ses->server->inFlight); 
+               wake_up(&ses->server->request_q);
+       }
 
-       DeleteMidQEntry(midQ);
-       atomic_dec(&ses->server->inFlight); 
-       wake_up(&ses->server->request_q);
+       return rc;
+
+out_unlock2:
+       up(&ses->server->tcpSem);
+       /* 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;
 }
@@ -620,34 +577,86 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
        /* Ensure that we do not send more than 50 overlapping requests 
           to the same server. We may make this configurable later or
           use ses->maxReq */
+       if(long_op == -1) {
+               /* oplock breaks must not be held up */
+               atomic_inc(&ses->server->inFlight);
+       } else {
+               spin_lock(&GlobalMid_Lock); 
+               while(1) {        
+                       if(atomic_read(&ses->server->inFlight) >= 
+                                       cifs_max_pending){
+                               spin_unlock(&GlobalMid_Lock);
+#ifdef CONFIG_CIFS_STATS2
+                               atomic_inc(&ses->server->num_waiters);
+#endif
+                               wait_event(ses->server->request_q,
+                                       atomic_read(&ses->server->inFlight)
+                                        < cifs_max_pending);
+#ifdef CONFIG_CIFS_STATS2
+                               atomic_dec(&ses->server->num_waiters);
+#endif
+                               spin_lock(&GlobalMid_Lock);
+                       } else {
+                               if(ses->server->tcpStatus == CifsExiting) {
+                                       spin_unlock(&GlobalMid_Lock);
+                                       return -ENOENT;
+                               }
 
-       rc = wait_for_free_request(ses, long_op);
-       if (rc)
-               return rc;
-
+                       /* can not count locking commands against total since
+                          they are allowed to block on server */
+                                       
+                               if(long_op < 3) {
+                               /* update # of requests on the wire to server */
+                                       atomic_inc(&ses->server->inFlight);
+                               }
+                               spin_unlock(&GlobalMid_Lock);
+                               break;
+                       }
+               }
+       }
        /* make sure that we sign in the same order that we send on this socket 
           and avoid races inside tcp sendmsg code that could cause corruption
           of smb data */
 
        down(&ses->server->tcpSem); 
 
-       rc = allocate_mid(ses, in_buf, &midQ);
-       if (rc) {
+       if (ses->server->tcpStatus == CifsExiting) {
+               rc = -ENOENT;
+               goto out_unlock;
+       } else if (ses->server->tcpStatus == CifsNeedReconnect) {
+               cFYI(1,("tcp session dead - return to caller to retry"));
+               rc = -EAGAIN;
+               goto out_unlock;
+       } else if (ses->status != CifsGood) {
+               /* check if SMB session is bad because we are setting it up */
+               if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 
+                       (in_buf->Command != SMB_COM_NEGOTIATE)) {
+                       rc = -EAGAIN;
+                       goto out_unlock;
+               } /* else ok - we are setting up session */
+       }
+       midQ = AllocMidQEntry(in_buf, ses);
+       if (midQ == NULL) {
                up(&ses->server->tcpSem);
-               /* Update # of requests on wire to server */
-               atomic_dec(&ses->server->inFlight); 
-               wake_up(&ses->server->request_q);
-               return rc;
+               /* 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 -ENOMEM;
        }
 
        if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
-               cERROR(1, ("Illegal length, greater than maximum frame, %d",
+               up(&ses->server->tcpSem);
+               cERROR(1,
+                      ("Illegal length, greater than maximum frame, %d ",
                        in_buf->smb_buf_length));
                DeleteMidQEntry(midQ);
-               up(&ses->server->tcpSem);
-               /* Update # of requests on wire to server */
-               atomic_dec(&ses->server->inFlight); 
-               wake_up(&ses->server->request_q);
+               /* 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 -EIO;
        }
 
@@ -663,19 +672,27 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
        atomic_dec(&ses->server->inSend);
        midQ->when_sent = jiffies;
 #endif
-       up(&ses->server->tcpSem);
-
-       if(rc < 0)
-               goto out;
-
+       if(rc < 0) {
+               DeleteMidQEntry(midQ);
+               up(&ses->server->tcpSem);
+               /* 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
+               up(&ses->server->tcpSem);
        if (long_op == -1)
-               goto out;
+               goto cifs_no_response_exit;
        else if (long_op == 2) /* writes past end of file can take loong time */
                timeout = 180 * HZ;
        else if (long_op == 1)
                timeout = 45 * HZ; /* should be greater than 
                        servers oplock break timeout (about 43 seconds) */
-       else
+       else if (long_op > 2) {
+               timeout = MAX_SCHEDULE_TIMEOUT;
+       } else
                timeout = 15 * HZ;
        /* wait for 15 seconds or until woken up due to response arriving or 
           due to last connection to this server being unmounted */
@@ -686,7 +703,19 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
        }   
 
        /* No user interrupts in wait - wreaks havoc with performance */
-       wait_for_response(ses, midQ, timeout, 10 * HZ);
+       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)));
+       } else {
+               wait_event(ses->server->response_q,
+                       (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
+                       ((ses->server->tcpStatus != CifsGood) &&
+                        (ses->server->tcpStatus != CifsNew)));
+       }
 
        spin_lock(&GlobalMid_Lock);
        if (midQ->resp_buf) {
@@ -714,9 +743,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                }
                spin_unlock(&GlobalMid_Lock);
                DeleteMidQEntry(midQ);
-               /* Update # of requests on wire to server */
-               atomic_dec(&ses->server->inFlight); 
-               wake_up(&ses->server->request_q);
+               /* 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;
        }
   
@@ -763,253 +794,23 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                        cERROR(1,("Bad MID state?"));
                }
        }
-
-out:
-
+cifs_no_response_exit:
        DeleteMidQEntry(midQ);
-       atomic_dec(&ses->server->inFlight); 
-       wake_up(&ses->server->request_q);
-
-       return rc;
-}
-
-/* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
-
-static int
-send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
-               struct mid_q_entry *midQ)
-{
-       int rc = 0;
-       struct cifsSesInfo *ses = tcon->ses;
-       __u16 mid = in_buf->Mid;
-
-       header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
-       in_buf->Mid = mid;
-       down(&ses->server->tcpSem); 
-       rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
-       if (rc) {
-               up(&ses->server->tcpSem);
-               return rc;
-       }
-       rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
-             (struct sockaddr *) &(ses->server->addr.sockAddr));
-       up(&ses->server->tcpSem);
-       return rc;
-}
-
-/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
-   blocking lock to return. */
-
-static int
-send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
-                       struct smb_hdr *in_buf,
-                       struct smb_hdr *out_buf)
-{
-       int bytes_returned;
-       struct cifsSesInfo *ses = tcon->ses;
-       LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
-
-       /* We just modify the current in_buf to change
-          the type of lock from LOCKING_ANDX_SHARED_LOCK
-          or LOCKING_ANDX_EXCLUSIVE_LOCK to
-          LOCKING_ANDX_CANCEL_LOCK. */
-
-       pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
-       pSMB->Timeout = 0;
-       pSMB->hdr.Mid = GetNextMid(ses->server);
-
-       return SendReceive(xid, ses, in_buf, out_buf,
-                       &bytes_returned, 0);
-}
-
-int
-SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
-           struct smb_hdr *in_buf, struct smb_hdr *out_buf,
-           int *pbytes_returned)
-{
-       int rc = 0;
-       int rstart = 0;
-       unsigned int receive_len;
-       struct mid_q_entry *midQ;
-       struct cifsSesInfo *ses;
-
-       if (tcon == NULL || tcon->ses == NULL) {
-               cERROR(1,("Null smb session"));
-               return -EIO;
-       }
-       ses = tcon->ses;
-
-       if(ses->server == NULL) {
-               cERROR(1,("Null tcp session"));
-               return -EIO;
-       }
-
-       if(ses->server->tcpStatus == CifsExiting)
-               return -ENOENT;
-
-       /* Ensure that we do not send more than 50 overlapping requests 
-          to the same server. We may make this configurable later or
-          use ses->maxReq */
 
-       rc = wait_for_free_request(ses, 3);
-       if (rc)
-               return rc;
-
-       /* make sure that we sign in the same order that we send on this socket 
-          and avoid races inside tcp sendmsg code that could cause corruption
-          of smb data */
-
-       down(&ses->server->tcpSem); 
-
-       rc = allocate_mid(ses, in_buf, &midQ);
-       if (rc) {
-               up(&ses->server->tcpSem);
-               return rc;
-       }
-
-       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",
-                       in_buf->smb_buf_length));
-               DeleteMidQEntry(midQ);
-               return -EIO;
+       if(long_op < 3) {
+               atomic_dec(&ses->server->inFlight); 
+               wake_up(&ses->server->request_q);
        }
 
-       rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
+       return rc;
 
-       midQ->midState = MID_REQUEST_SUBMITTED;
-#ifdef CONFIG_CIFS_STATS2
-       atomic_inc(&ses->server->inSend);
-#endif
-       rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
-                     (struct sockaddr *) &(ses->server->addr.sockAddr));
-#ifdef CONFIG_CIFS_STATS2
-       atomic_dec(&ses->server->inSend);
-       midQ->when_sent = jiffies;
-#endif
+out_unlock:
        up(&ses->server->tcpSem);
-
-       if(rc < 0) {
-               DeleteMidQEntry(midQ);
-               return rc;
-       }
-
-       /* Wait for a reply - allow signals to interrupt. */
-       rc = wait_event_interruptible(ses->server->response_q,
-               (!(midQ->midState == MID_REQUEST_SUBMITTED)) || 
-               ((ses->server->tcpStatus != CifsGood) &&
-                (ses->server->tcpStatus != CifsNew)));
-
-       /* Were we interrupted by a signal ? */
-       if ((rc == -ERESTARTSYS) &&
-               (midQ->midState == MID_REQUEST_SUBMITTED) &&
-               ((ses->server->tcpStatus == CifsGood) ||
-                (ses->server->tcpStatus == CifsNew))) {
-
-               if (in_buf->Command == SMB_COM_TRANSACTION2) {
-                       /* POSIX lock. We send a NT_CANCEL SMB to cause the
-                          blocking lock to return. */
-
-                       rc = send_nt_cancel(tcon, in_buf, midQ);
-                       if (rc) {
-                               DeleteMidQEntry(midQ);
-                               return rc;
-                       }
-               } else {
-                       /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
-                          to cause the blocking lock to return. */
-
-                       rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
-
-                       /* If we get -ENOLCK back the lock may have
-                          already been removed. Don't exit in this case. */
-                       if (rc && rc != -ENOLCK) {
-                               DeleteMidQEntry(midQ);
-                               return rc;
-                       }
-               }
-
-               /* Wait 5 seconds for the response. */
-               if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ)==0) {
-                       /* We got the response - restart system call. */
-                       rstart = 1;
-               }
-       }
-
-       spin_lock(&GlobalMid_Lock);
-       if (midQ->resp_buf) {
-               spin_unlock(&GlobalMid_Lock);
-               receive_len = midQ->resp_buf->smb_buf_length;
-       } else {
-               cERROR(1,("No response for cmd %d mid %d",
-                         midQ->command, midQ->mid));
-               if(midQ->midState == MID_REQUEST_SUBMITTED) {
-                       if(ses->server->tcpStatus == CifsExiting)
-                               rc = -EHOSTDOWN;
-                       else {
-                               ses->server->tcpStatus = CifsNeedReconnect;
-                               midQ->midState = MID_RETRY_NEEDED;
-                       }
-               }
-
-               if (rc != -EHOSTDOWN) {
-                       if(midQ->midState == MID_RETRY_NEEDED) {
-                               rc = -EAGAIN;
-                               cFYI(1,("marking request for retry"));
-                       } else {
-                               rc = -EIO;
-                       }
-               }
-               spin_unlock(&GlobalMid_Lock);
-               DeleteMidQEntry(midQ);
-               return rc;
+       /* 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);
        }
-  
-       if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
-               cERROR(1, ("Frame too large received.  Length: %d  Xid: %d",
-                       receive_len, xid));
-               rc = -EIO;
-       } else {                /* rcvd frame is ok */
-
-               if (midQ->resp_buf && out_buf
-                   && (midQ->midState == MID_RESPONSE_RECEIVED)) {
-                       out_buf->smb_buf_length = receive_len;
-                       memcpy((char *)out_buf + 4,
-                              (char *)midQ->resp_buf + 4,
-                              receive_len);
 
-                       dump_smb(out_buf, 92);
-                       /* convert the length into a more usable form */
-                       if((receive_len > 24) &&
-                          (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
-                                       SECMODE_SIGN_ENABLED))) {
-                               rc = cifs_verify_signature(out_buf,
-                                               ses->server->mac_signing_key,
-                                               midQ->sequence_number+1);
-                               if(rc) {
-                                       cERROR(1,("Unexpected SMB signature"));
-                                       /* BB FIXME add code to kill session */
-                               }
-                       }
-
-                       *pbytes_returned = out_buf->smb_buf_length;
-
-                       /* BB special case reconnect tid and uid here? */
-                       rc = map_smb_to_linux_error(out_buf);
-
-                       /* convert ByteCount if necessary */
-                       if (receive_len >=
-                           sizeof (struct smb_hdr) -
-                           4 /* do not count RFC1001 header */  +
-                           (2 * out_buf->WordCount) + 2 /* bcc */ )
-                               BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
-               } else {
-                       rc = -EIO;
-                       cERROR(1,("Bad MID state?"));
-               }
-       }
-       DeleteMidQEntry(midQ);
-       if (rstart && rc == -EACCES)
-               return -ERESTARTSYS;
        return rc;
 }