From a2d8f9d2fc6712c2905e883ade31a8f173605705 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Thu, 22 Sep 2016 20:34:44 +0000 Subject: [PATCH] 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 --- sys/kern/kern_sendfile.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c index a2a258d53000..cac4d3649e64 100644 --- a/sys/kern/kern_sendfile.c +++ b/sys/kern/kern_sendfile.c @@ -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;