[linux-cifs-client] Re: strange tcp peek behavior confuses cifs
demultiplexing
Steve French
smfrench at austin.rr.com
Tue Dec 14 16:21:22 GMT 2004
Ok - this seems straightforward problem (although one I did not believe
could happen with Linux TCP/IP stack) and the approach I tried isn't
going to work without a slightly different change.
Background:
cifs has a kernel thread which reads data from each server we have a
mount to (one thread per server socket).
This "demultiplex thread" basically does:
while(not shutting down/unmounting) {
Peek to see if it is an SMB response
If valid RFC1001 frame but not SMB
continue
If SMB is not valid {
/* assume something bad happened to server */
kill session
reconnect session
continue
}
while(data left in SMB to read off socket)
Read SMB from socket
find which task is waiting for this smb
wake up the task waiting on this smb
}
The problem here is that I need at least 4 bytes returned from the peek
to be able to determine the length and RFC1001 frame type. So I have to
get 4 bytes (but since I can't imagine the tcp stack returning fewer
than that on the peek since at a minimum the servers send
sizeof(smb_header) in one tcp send, this has never been a problem).
Here though the stack is returning only 3 bytes of the SMB header on the
peek! Originally I had been assuming that the peek would always return
what the server sent which would be either a 4 byte keep alive or
sizeof(smb header) bytes (followed by a second send of the data) or a
full SMB - obviously the stack does not always return on peek the
corresponding size to the servers tcp sendmsg - so then I relaxed that
to assume that if we did not get 14 bytes (enough to read the smb flags
and tell if this was an smb response) - don't check the SMB flags (they
get checked later anyway) - but we still need at least 4 bytes off the
peek (otherwise I don't have the full length field and I can't tell how
much to read off the socket). Sounds like on the 3 byte peek I need to
sleep for perhaps a millisecond, then try again until I get that 4th
byte. Note that I am expecting an error if the socket really is dead -
I am not expecting a tiny peek. Getting the 3 byte peek confused the
next read which started 3 bytes off and did not parse as an SMB.
The fix on the peek less than 4 bytes is presumably to not read it off
the socket, but to sleep a short time and continue retrying the peek.
Gorazd Golob wrote:
>Hi!
>
>Here is reproduces the problem reproduced with this new patch.. I guess
>something else went wrong. Below are two things as usual .. snip from
>dmesg (with cifsFYI on) and kernel oops with ksymoops. Hope it helps.
>
>--- dmesg ---
>
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/connect.c: Peek length rcvd:
>0x24 beginning 0x1044)
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/transport.c: For smb_command 46
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/transport.c: Sending smb of
>length 59
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/connect.c: Mid 0xe667 matched -
>waking up
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/connect.c: Peek length rcvd:
>0x24 beginning 0x1044)
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/transport.c: For smb_command 46
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/transport.c: Sending smb of
>length 59
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/connect.c: Mid 0xe668 matched -
>waking up
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/connect.c: Peek length rcvd: 0x3
>beginning 0x1004)
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/connect.c: with junk 0x100000
>in it
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/transport.c: For smb_command 46
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/transport.c: Sending smb of
>length 59
>Dec 14 08:40:59 delovc10 kernel: fs/cifs/connect.c: Peek length rcvd:
>0x24 beginning 0x40ff5351)
>Dec 14 08:40:59 delovc10 kernel: CIFS VFS: Unknown RFC 1002 frame
>Dec 14 08:40:59 delovc10 kernel: Received Data: : dump of 36 bytes of
>data at 0xe95007a0
>Dec 14 08:40:59 delovc10 kernel:
>Dec 14 08:41:00 delovc10 kernel: 4d53ff40 00002e42 01800000 000000c0 @ ÿ
>S M B . . . . . . . À . . .
>Dec 14 08:41:00 delovc10 kernel: 00000000 00000000 76080000 69080009 . .
>. . . . . . . . . v . . . i
>Dec 14 08:41:00 delovc10 kernel: 00ff0ce6 æ . ÿ .
>Dec 14 08:41:00 delovc10 kernel: fs/cifs/connect.c: Reconnecting tcp
>session
>
>
More information about the linux-cifs-client
mailing list