]> err.no Git - linux-2.6/commitdiff
[CIFS] fix for incorrect session reconnects
authorSteve French <sfrench@us.ibm.com>
Thu, 30 Aug 2007 21:13:31 +0000 (21:13 +0000)
committerSteve French <sfrench@us.ibm.com>
Thu, 30 Aug 2007 21:13:31 +0000 (21:13 +0000)
cifs reconnect could end up happening incorrectly due to
the small initial tcp recvmsg response. When the socket
was within three bytes of being full and the recvmsg
returned only 1 to 3 bytes of the initial 4 byte
read of the RFC1001 length field. Fortunately this
seems to be less common on more current kernels, but
this fixes it so cifs tries to retrieve all 4 bytes
of the initial tcp read.

Signed-off-by: Shirish Pargoankar <shirishp@us.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/connect.c

index 4af3588c1a9615b39976bac9fadc3487a64025eb..8af993f8d0ccfc2689c3f81c20bfe7d4c59d4168 100644 (file)
@@ -400,9 +400,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                iov.iov_len = 4;
                smb_msg.msg_control = NULL;
                smb_msg.msg_controllen = 0;
+               pdu_length = 4; /* enough to get RFC1001 header */
+incomplete_rcv:
                length =
                    kernel_recvmsg(csocket, &smb_msg,
-                                &iov, 1, 4, 0 /* BB see socket.h flags */);
+                               &iov, 1, pdu_length, 0 /* BB other flags? */);
 
                if ( kthread_should_stop() ) {
                        break;
@@ -437,13 +439,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                        wake_up(&server->response_q);
                        continue;
                } else if (length < 4) {
-                       cFYI(1,
-                           ("Frame under four bytes received (%d bytes long)",
+                       cFYI(1, ("less than four bytes received (%d bytes)",
                              length));
+                       pdu_length -= length;
                        cifs_reconnect(server);
-                       csocket = server->ssocket;
-                       wake_up(&server->response_q);
-                       continue;
+                       msleep(1);
+                       goto incomplete_rcv;
                }
 
                /* The right amount was read from socket - 4 bytes */