]> git.hungrycats.org Git - linux/commitdiff
lock session when reconnecting so we do not oops in retrying sendmsg
authorSteve French <stevef@smfhome.smfdom>
Sun, 13 Jun 2004 16:10:19 +0000 (11:10 -0500)
committerSteve French <stevef@smfhome.smfdom>
Sun, 13 Jun 2004 16:10:19 +0000 (11:10 -0500)
Signed-off-by: Steve French (sfrench@us.ibm.com)
fs/cifs/connect.c
fs/cifs/transport.c

index 48554f057dc0eb9ad7fb18aa54605d27a05af388..a995c4949e56e88c5c19017c5bd9a10507e4b0e6 100644 (file)
@@ -128,7 +128,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
                }
        }
        read_unlock(&GlobalSMBSeslock);
-
+       /* do not want to be sending data on a socket we are freeing */
+       down(&server->tcpSem); 
        if(server->ssocket) {
                cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state,
                        server->ssocket->flags));
@@ -154,7 +155,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
                }
        }
        spin_unlock(&GlobalMid_Lock);
-
+       up(&ses->server->tcpSem); 
 
        while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
        {
index 48194f7cd7a7f034a8e43bfc52453a504cddec57..3668ab00b3ef2a290287510a8051dd7d77affae6 100644 (file)
@@ -120,6 +120,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
         unsigned int smb_buf_length, struct sockaddr *sin)
 {
        int rc = 0;
+       int i = 0;
        struct msghdr smb_msg;
        struct iovec iov;
        mm_segment_t temp_fs;
@@ -151,6 +152,14 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
        while(iov.iov_len > 0) {
                rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4);
                if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
+                       i++;
+                       if(i > 60) {
+                               cERROR(1,
+                                  ("sends on sock %p stuck for 30 seconds",
+                                   ssocket));
+                               rc = -EAGAIN;
+                               break;
+                       }
                        set_current_state(TASK_INTERRUPTIBLE);
                        schedule_timeout(HZ/2);
                        continue;
@@ -259,7 +268,17 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
        midQ->midState = MID_REQUEST_SUBMITTED;
        rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
                      (struct sockaddr *) &(ses->server->addr.sockAddr));
-       up(&ses->server->tcpSem);
+       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 cifs_no_response_exit;
        else if (long_op == 2) /* writes past end of file can take looooong time */