The need for a special SMB receive system call

Richard Sharpe rsharpe at
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[1].

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 
Write&X request.

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. [2]

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 
and return. 

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.

[1] Ignore issues around NetBIOS messages etc for the moment.

[2] Max read bandwidth from a test machine reduces from about 99MB/s on 
GigE to about 97MB/s.

Richard Sharpe, rsharpe at, rsharpe at, 
sharpe at

More information about the samba-technical mailing list