Refactor out the sendfile copyout in order to make vn_sendfile()

callable from the kernel.

Right now vn_sendfile() can't be called from anything other than
a syscall handler _and_ return the number of bytes queued.
This simply moves the copyout() to do_sendfile() so that any kernel
code can initiate vn_sendfile() outside of a syscall context.

Tested:

* tiny little sendfile program spitting things out a tcp socket

Sponsored by:	Netflix, Inc.
This commit is contained in:
Adrian Chadd 2013-11-26 02:02:05 +00:00
parent 39bb444c76
commit 3287361e38
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=258613

View File

@ -1908,6 +1908,7 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat)
struct file *fp; struct file *fp;
cap_rights_t rights; cap_rights_t rights;
int error; int error;
off_t sbytes;
/* /*
* File offset must be positive. If it goes beyond EOF * File offset must be positive. If it goes beyond EOF
@ -1947,9 +1948,11 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat)
} }
error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, uap->offset, error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, uap->offset,
uap->nbytes, uap->sbytes, uap->flags, compat ? SFK_COMPAT : 0, td); uap->nbytes, &sbytes, uap->flags, compat ? SFK_COMPAT : 0, td);
fdrop(fp, td); fdrop(fp, td);
if (uap->sbytes != NULL) {
copyout(&sbytes, uap->sbytes, sizeof(off_t));
}
out: out:
free(hdr_uio, M_IOV); free(hdr_uio, M_IOV);
free(trl_uio, M_IOV); free(trl_uio, M_IOV);
@ -2546,7 +2549,7 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
td->td_retval[0] = 0; td->td_retval[0] = 0;
} }
if (sent != NULL) { if (sent != NULL) {
copyout(&sbytes, sent, sizeof(off_t)); (*sent) = sbytes;
} }
if (obj != NULL) if (obj != NULL)
vm_object_deallocate(obj); vm_object_deallocate(obj);