[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