The need for a special SMB receive system call
rsharpe at ns.aus.com
Tue Sep 24 21:09:01 GMT 2002
In the course of hacking Samba to use the recv variant of sendfile I have
had to modify the low level routines that read in an SMB off of a socket.
Currently, Samba makes two system calls to reveive an SMB, one to receive
the length and the other to receive the rest of the SMB.
Because I wanted to leave write data on the socket for Write&X calls, and
have this data transferred directly to the open file in the case where it
can be safely done (Ie, we have an oplock on the file etc), I had to split
that into a minumum of three reads: One to read the length, another to
read to the end of the fixed header of the SMB so we can check the command
type, and that last one to read out the rest of the data if it is not a
If the request turns out to be a Write&X, we must make another system call
to read up to the data portion; the recvfile/sendfile syscall handles the
rest of the data later.
Now, adding an extra system call introduces a small performance penalty,
which seems to be about 2-3 percent, but it also complicates the code a
great deal. 
What would be useful would be to have a system call that can read an SMB
off a socket and do all the above stuff in the kernel. If the extra system
call is costing about 2-3%, then collapsing them all into one would
possibly improve performance slightly. It would also reduce the complexity
in the code changes somewhat.
This call would take a socket, a buffer, max size of buffer, a match
offset, match value, and match read amount and possibly a timeout, and
would perform the above steps in the kernel. Read the first four bytes,
extract the lenght, then read up to and including the match offset, check
for the match value. If no match, copy the rest of the SMB into userspace
and return. If there is a match, copy the match read amount to user space
Oh, and by the way, implementing recvfile and the above changes allows
write performance to go up from 27MB/s to 45MB/s for a single client on an
850MHz FreeBSD system when writing to a memory file system. CPU was
saturated, however, in both cases.
 Ignore issues around NetBIOS messages etc for the moment.
 Max read bandwidth from a test machine reduces from about 99MB/s on
GigE to about 97MB/s.
Richard Sharpe, rsharpe at ns.aus.com, rsharpe at samba.org,
sharpe at ethereal.com
More information about the samba-technical