Fix regression from r297400, which truncates headers in case of low socket

buffer and put a small optimization for low socket buffer case:

- Do not hack uio_resid, and let m_uiotombuf() properly take care of it. This
  fixes truncation of headers at low buffer.
- If headers ate all the space, jump right to the end of the cycle, to
  avoid doing single page I/O and allocating zero length mbuf.
- Clear hdr_uio only if space is positive, which indicates that all uio
  was copied in.

Reviewed by:	pluknet, jtl, emax, rrs, lstewart, emax, gallatin, scottl
This commit is contained in:
Gleb Smirnoff 2016-09-22 20:34:44 +00:00
parent 2faa9f8c8e
commit a2d8f9d2fc

View File

@ -656,10 +656,18 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
if (hdr_uio != NULL && hdr_uio->uio_resid > 0) {
hdr_uio->uio_td = td;
hdr_uio->uio_rw = UIO_WRITE;
hdr_uio->uio_resid = min(hdr_uio->uio_resid, space);
mh = m_uiotombuf(hdr_uio, M_WAITOK, 0, 0, 0);
mh = m_uiotombuf(hdr_uio, M_WAITOK, space, 0, 0);
hdrlen = m_length(mh, &mhtail);
space -= hdrlen;
/*
* If header consumed all the socket buffer space,
* don't waste CPU cycles and jump to the end.
*/
if (space == 0) {
sfio = NULL;
nios = 0;
goto prepend_header;
}
hdr_uio = NULL;
}
@ -806,6 +814,7 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
/* Prepend header, if any. */
if (hdrlen) {
prepend_header:
mhtail->m_next = m;
m = mh;
mh = NULL;