At least on a heavily patched 2.6.35.9, we can see splice() fail
with EBADF :
recv(6, "789.
123456789.
123456789.
12345678"..., 1049, 0) = 1049
send(5, "HTTP/1.1 200\r\nContent-length: 10"..., 8030, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE) = 8030
gettimeofday({
1352717854, 515601}, NULL) = 0
epoll_wait(0x3, 0x40221008, 0x7, 0) = 0
gettimeofday({
1352717854, 515793}, NULL) = 0
pipe([7, 8]) = 0
splice(0x6, 0, 0x8, 0, 0xfe12c, 0x3) = -1 EBADF (Bad file descriptor)
close(6) = 0
This clearly is a kernel issue since all FDs are valid here, so let's
simply disable splice() on the connection when this happens so that
the session correctly recovers from that issue using recv().
__conn_data_poll_recv(conn); /* we know for sure that it's EAGAIN */
break;
}
- else if (errno == ENOSYS || errno == EINVAL) {
+ else if (errno == ENOSYS || errno == EINVAL || errno == EBADF) {
/* splice not supported on this end, disable it.
* We can safely return -1 since there is no
* chance that any data has been piped yet.