]> err.no Git - linux-2.6/blobdiff - fs/cifs/transport.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild
[linux-2.6] / fs / cifs / transport.c
index 893a6fef98530ec206b1516bc89589f351dd66c4..981ea0d8b9cdaa4b06f53f7fdae975b41a1bffa6 100644 (file)
@@ -59,7 +59,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
                temp->pid = current->pid;
                temp->command = smb_buffer->Command;
                cFYI(1, ("For smb_command %d", temp->command));
-               do_gettimeofday(&temp->when_sent);
+       /*      do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
+               /* when mid allocated can be before when sent */
+               temp->when_alloc = jiffies;
                temp->ses = ses;
                temp->tsk = current;
        }
@@ -75,6 +77,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
 static void
 DeleteMidQEntry(struct mid_q_entry *midEntry)
 {
+#ifdef CONFIG_CIFS_STATS2
+       unsigned long now;
+#endif
        spin_lock(&GlobalMid_Lock);
        midEntry->midState = MID_FREE;
        list_del(&midEntry->qhead);
@@ -84,6 +89,22 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
                cifs_buf_release(midEntry->resp_buf);
        else
                cifs_small_buf_release(midEntry->resp_buf);
+#ifdef CONFIG_CIFS_STATS2
+       now = jiffies;
+       /* commands taking longer than one second are indications that
+          something is wrong, unless it is quite a slow link or server */
+       if((now - midEntry->when_alloc) > HZ) {
+               if((cifsFYI & CIFS_TIMER) && 
+                  (midEntry->command != SMB_COM_LOCKING_ANDX)) {
+                       printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
+                              midEntry->command, midEntry->mid);
+                       printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
+                              now - midEntry->when_alloc,
+                              now - midEntry->when_sent,
+                              now - midEntry->when_received);
+               }
+       }
+#endif
        mempool_free(midEntry, cifs_mid_poolp);
 }
 
@@ -157,18 +178,20 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
                /* smaller timeout here than send2 since smaller size */
                /* Although it may not be required, this also is smaller 
                   oplock break time */  
-                       if(i > 30) {
+                       if(i > 12) {
                                cERROR(1,
-                                  ("sends on sock %p stuck for 15 seconds",
+                                  ("sends on sock %p stuck for 7 seconds",
                                    ssocket));
                                rc = -EAGAIN;
                                break;
                        }
-                       msleep(500);
+                       msleep(1 << i);
                        continue;
                }
                if (rc < 0) 
                        break;
+               else
+                       i = 0; /* reset i after each successful send */
                iov.iov_base += rc;
                iov.iov_len -= rc;
                len -= rc;
@@ -224,14 +247,14 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
                                    n_vec - first_vec, total_len);
                if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
                        i++;
-                       if(i > 40) {
+                       if(i >= 14) {
                                cERROR(1,
-                                  ("sends on sock %p stuck for 20 seconds",
+                                  ("sends on sock %p stuck for 15 seconds",
                                    ssocket));
                                rc = -EAGAIN;
                                break;
                        }
-                       msleep(500);
+                       msleep(1 << i);
                        continue;
                }
                if (rc < 0) 
@@ -249,6 +272,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
                        continue;
                }
                total_len -= rc;
+               /* the line below resets i */
                for (i = first_vec; i < n_vec; i++) {
                        if (iov[i].iov_len) {
                                if (rc > iov[i].iov_len) {
@@ -262,6 +286,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
                                }
                        }
                }
+               i = 0; /* in case we get ENOSPC on the next send */
        }
 
        if (rc < 0) {
@@ -378,6 +403,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                      (struct sockaddr *) &(ses->server->addr.sockAddr));
 #ifdef CONFIG_CIFS_STATS2
        atomic_dec(&ses->server->inSend);
+       midQ->when_sent = jiffies;
 #endif
        if(rc < 0) {
                DeleteMidQEntry(midQ);
@@ -642,6 +668,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                      (struct sockaddr *) &(ses->server->addr.sockAddr));
 #ifdef CONFIG_CIFS_STATS2
        atomic_dec(&ses->server->inSend);
+       midQ->when_sent = jiffies;
 #endif
        if(rc < 0) {
                DeleteMidQEntry(midQ);