[CIFS] Can't rely on iov length and base when kernel_recvmsg returns error
authorSteve French <sfrench@us.ibm.com>
Mon, 3 Nov 2008 20:46:21 +0000 (20:46 +0000)
committerSteve French <sfrench@us.ibm.com>
Mon, 3 Nov 2008 20:46:21 +0000 (20:46 +0000)
When retrying kernel_recvmsg, reset iov_base and iov_len.

Note comment from Sridhar: "In the normal path, iov.iov_len is clearly set to 4. But i think you are
running into a case where kernel_recvmsg() is called via 'goto incomplete_rcv'
It happens if the previous call fails with EAGAIN.
If you want to call recvmsg() after EAGAIN failure, you need to reset iov."

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

index e9f9248cb3feff13deeeb4d5eeae1d2a65f79ebe..c682be8f298413a24d7d123cef7368694d123dbd 100644 (file)
@@ -417,9 +417,14 @@ incomplete_rcv:
                        msleep(1); /* minimum sleep to prevent looping
                                allowing socket to clear and app threads to set
                                tcpStatus CifsNeedReconnect if server hung */
-                       if (pdu_length < 4)
+                       if (pdu_length < 4) {
+                               iov.iov_base = (4 - pdu_length) +
+                                                       (char *)smb_buffer;
+                               iov.iov_len = pdu_length;
+                               smb_msg.msg_control = NULL;
+                               smb_msg.msg_controllen = 0;
                                goto incomplete_rcv;
-                       else
+                       else
                                continue;
                } else if (length <= 0) {
                        if (server->tcpStatus == CifsNew) {