Browse Source

[CIFS] Can't rely on iov length and base when kernel_recvmsg returns error

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>
Steve French 16 years ago
parent
commit
c527c8a7ff
1 changed files with 7 additions and 2 deletions
  1. 7 2
      fs/cifs/connect.c

+ 7 - 2
fs/cifs/connect.c

@@ -417,9 +417,14 @@ incomplete_rcv:
 			msleep(1); /* minimum sleep to prevent looping
 			msleep(1); /* minimum sleep to prevent looping
 				allowing socket to clear and app threads to set
 				allowing socket to clear and app threads to set
 				tcpStatus CifsNeedReconnect if server hung */
 				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;
 				goto incomplete_rcv;
-			else
+			} else
 				continue;
 				continue;
 		} else if (length <= 0) {
 		} else if (length <= 0) {
 			if (server->tcpStatus == CifsNew) {
 			if (server->tcpStatus == CifsNew) {