MINOR: splice: disable it when the system returns EBADF

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().
This commit is contained in:
Willy Tarreau 2012-11-12 12:00:09 +01:00
parent 674b743067
commit 45b8893966

View File

@ -129,7 +129,7 @@ int raw_sock_to_pipe(struct connection *conn, struct pipe *pipe, unsigned int co
__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.