diff options
author | Steve French <sfrench@us.ibm.com> | 2007-08-30 17:13:31 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2007-08-30 17:13:31 -0400 |
commit | f01d5e14e764b14b6bf5512678523d009254b209 (patch) | |
tree | a83c839bb84d9ef7e9c8accf60cf572bf6b55ce0 /fs | |
parent | 8594c15ad226227aaf178b7cf57f2e7291684dd4 (diff) |
[CIFS] fix for incorrect session reconnects
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/connect.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 4af3588c1a96..8af993f8d0cc 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -400,9 +400,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
400 | iov.iov_len = 4; | 400 | iov.iov_len = 4; |
401 | smb_msg.msg_control = NULL; | 401 | smb_msg.msg_control = NULL; |
402 | smb_msg.msg_controllen = 0; | 402 | smb_msg.msg_controllen = 0; |
403 | pdu_length = 4; /* enough to get RFC1001 header */ | ||
404 | incomplete_rcv: | ||
403 | length = | 405 | length = |
404 | kernel_recvmsg(csocket, &smb_msg, | 406 | kernel_recvmsg(csocket, &smb_msg, |
405 | &iov, 1, 4, 0 /* BB see socket.h flags */); | 407 | &iov, 1, pdu_length, 0 /* BB other flags? */); |
406 | 408 | ||
407 | if ( kthread_should_stop() ) { | 409 | if ( kthread_should_stop() ) { |
408 | break; | 410 | break; |
@@ -437,13 +439,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
437 | wake_up(&server->response_q); | 439 | wake_up(&server->response_q); |
438 | continue; | 440 | continue; |
439 | } else if (length < 4) { | 441 | } else if (length < 4) { |
440 | cFYI(1, | 442 | cFYI(1, ("less than four bytes received (%d bytes)", |
441 | ("Frame under four bytes received (%d bytes long)", | ||
442 | length)); | 443 | length)); |
444 | pdu_length -= length; | ||
443 | cifs_reconnect(server); | 445 | cifs_reconnect(server); |
444 | csocket = server->ssocket; | 446 | msleep(1); |
445 | wake_up(&server->response_q); | 447 | goto incomplete_rcv; |
446 | continue; | ||
447 | } | 448 | } |
448 | 449 | ||
449 | /* The right amount was read from socket - 4 bytes */ | 450 | /* The right amount was read from socket - 4 bytes */ |