[PATCH] Fix bug 9412 - SMB2 server doesn't support recvfile.

Jeremy Allison jra at samba.org
Thu May 22 16:04:23 MDT 2014


On Thu, May 22, 2014 at 02:24:03PM -0700, Jeremy Allison wrote:
> On Thu, May 22, 2014 at 10:24:13AM +0800, Jones wrote:
> > 2014-04-18 0:10 GMT+08:00 Jeremy Allison <jra at samba.org>:
> >      (and remember your trace shows
> >      EAGAIN coming back explicitly
> >      after we've remove the O_NONBLOCK
> >      from the socket flag).
> > 
> > Hello Jeremy,
> > 
> > Yes! this symptom was a bit confusing for me,
> > after digging further found that source, 
> > this EAGAIN is came from kernel tcp_recvmsg()
> > @ linux-3.4.6/net/ipv4/tcp.c
> > ...
> > if (!timeo) {
> > copied = -EAGAIN;  // <--- came from here.
> > break;
> > }
> > ...
> > 
> > Excuse me to explain more about my linux box, 
> > though following part hmm ... just a bit samba code involved, 
> > most of them are inside kernel.
> 
> Yeah, looks like your custom splice
> impliticly sets a SO_RCVTIMEO on
> the socket.
> 
> Looking at the man page for recv()
> we have:
> 
>        EAGAIN or EWOULDBLOCK
>               The socket is marked nonblocking and the receive operation would block, or a receive timeout had been set  and  the
>               timeout  expired before data was received.  POSIX.1-2001 allows either error to be returned for this case, and does
>               not require these constants to have the same value, so a portable application should check for both possibilities.
> 
> so it is possible that even when
> the socket it set blocking that
> a recv() or splice() call can
> return EAGAIN or EWOULDBLOCK.

Hmmm. By default (unless you have
set the SO_RCVTIMEO in the smb.conf
socket options parameter) the timeout
value is set to zero - which means
that a recv() or splice() call would
*never* timeout or return EAGAIN
when the socket it set to blocking
mode.

Looking your custom patch here:

https://lkml.org/lkml/2013/7/22/639

I see:

+	rcvtimeo = sock->sk->sk_rcvtimeo;    
+	sock->sk->sk_rcvtimeo = 8 * HZ;
+
+	ret = kernel_recvmsg(sock, &msg, &iov[0], cPagesAllocated, count,
+			     MSG_WAITALL | MSG_NOCATCHSIG);
+
+	sock->sk->sk_rcvtimeo = rcvtimeo;

Can you remove the lines:

+       rcvtimeo = sock->sk->sk_rcvtimeo;    
+       sock->sk->sk_rcvtimeo = 8 * HZ;

...

+       sock->sk->sk_rcvtimeo = rcvtimeo;

and just leave the sk_rcvtimeo alone ?

I think that will prevent the splice()
from returning EAGAIN once the socket
is set to blocking mode.

I don't understand why it's messing with
sock->sk->sk_rcvtimeo in the first place,
it really shouldn't be doing that...

It's things like this that are why this
code didn't get accepted in the kernel
in the first place :-).

Jeremy


More information about the samba-technical mailing list