sendfile does the following: if (uap->hdtr != NULL) { .... if (hdtr.headers != NULL) { ... error = writev(p, &nuap); sbytes += p->p_retval[0]; } } if we have headers, sbytes > 0 next, in the main loop we do the following: ... if (uap->nbytes && xfsize > (uap->nbytes - sbytes)) xfsize = uap->nbytes - sbytes; in this code we think that sbytes accumulates only file`s contents. Therefore, the last NNN bytes of file will be forgotten. (NNN = p->p_retval[0] fron writev) Fix: use separate counter for the header size: off_t off, xfsize, sbytes = 0, sbytes1 = 0; .... if (hdtr.headers != NULL) { nuap.fd = uap->s; nuap.iovp = hdtr.headers; nuap.iovcnt = hdtr.hdr_cnt; error = writev(p, &nuap); if (error) goto done; sbytes1 = p->p_retval[0]; } .... done: if (uap->sbytes != NULL) { sbytes += sbytes1; copyout(&sbytes, uap->sbytes, sizeof(off_t)); } How-To-Repeat: .
Here is a patch: Index: uipc_syscalls.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.65.2.9 diff -u -r1.65.2.9 uipc_syscalls.c --- uipc_syscalls.c 2001/07/31 10:49:39 1.65.2.9 +++ uipc_syscalls.c 2002/01/22 15:01:42 @@ -1532,10 +1532,11 @@ struct vm_page *pg; struct writev_args nuap; struct sf_hdtr hdtr; - off_t off, xfsize, sbytes = 0; + off_t off, xfsize, hdtr_size, sbytes = 0; int error = 0, s; vp = NULL; + hdtr_size = 0; /* * Do argument checking. Must be a regular file in, stream * type and connected socket out, positive offset. @@ -1591,7 +1592,7 @@ error = writev(p, &nuap); if (error) goto done; - sbytes += p->p_retval[0]; + hdtr_size += p->p_retval[0]; } } @@ -1831,11 +1832,12 @@ error = writev(p, &nuap); if (error) goto done; - sbytes += p->p_retval[0]; + hdtr_size += p->p_retval[0]; } done: if (uap->sbytes != NULL) { + sbytes += hdtr_size; copyout(&sbytes, uap->sbytes, sizeof(off_t)); } if (vp) -- Maxim Konovalov, MAcomnet, Internet-Intranet Dept., system engineer phone: +7 (095) 796-9079, mailto: maxim@macomnet.ru
Responsible Changed From-To: freebsd-bugs->dg David, this looks closely related to the work you're discussing with Alfred in connection with sendfile().
State Changed From-To: open->closed alfred fixed this bug in rev. 1.103 and rev. 1.65.2.10 src/sys/kern/uipc_syscalls.c in -CURRENT and -STABLE six months ago.