Index: sys/compat/freebsd32/freebsd32_misc.c =================================================================== --- sys/compat/freebsd32/freebsd32_misc.c (revision 260414) +++ sys/compat/freebsd32/freebsd32_misc.c (working copy) @@ -86,6 +86,7 @@ #include #include #include +#include #ifdef INET #include @@ -1651,8 +1652,6 @@ struct sf_hdtr hdtr; struct uio *hdr_uio, *trl_uio; struct iovec32 *iov32; - struct file *fp; - cap_rights_t rights; off_t offset; int error; off_t sbytes; @@ -1690,29 +1689,9 @@ } } - AUDIT_ARG_FD(uap->fd); + error = _do_sendfile(td, uap->fd, uap->s, uap->flags, compat, + offset, uap->nbytes, &sbytes, hdr_uio, trl_uio); - if ((error = fget_read(td, uap->fd, - cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) { - goto out; - } - - /* - * If we need to wait for completion, initialise the sfsync - * state here. - */ - if (uap->flags & SF_SYNC) - sfs = sf_sync_alloc(uap->flags & SF_SYNC); - - error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset, - uap->nbytes, &sbytes, uap->flags, compat ? SFK_COMPAT : 0, - sfs, td); - if (sfs != NULL) { - sf_sync_syscall_wait(sfs); - sf_sync_free(sfs); - } - - fdrop(fp, td); if (uap->sbytes != NULL) copyout(&sbytes, uap->sbytes, sizeof(off_t)); Index: sys/kern/uipc_syscalls.c =================================================================== --- sys/kern/uipc_syscalls.c (revision 260414) +++ sys/kern/uipc_syscalls.c (working copy) @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -1988,16 +1989,63 @@ return (do_sendfile(td, uap, 0)); } +int +_do_sendfile(struct thread *td, int src_fd, int sock_fd, int flags, + int compat, off_t offset, size_t nbytes, off_t *sbytes, + struct uio *hdr_uio, struct uio *trl_uio) +{ + cap_rights_t rights; + struct sendfile_sync *sfs = NULL; + struct file *fp; + int error; + + AUDIT_ARG_FD(src_fd); + + /* + * sendfile(2) can start at any offset within a file so we require + * CAP_READ+CAP_SEEK = CAP_PREAD. + */ + if ((error = fget_read(td, src_fd, + cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) { + goto out; + } + + /* + * If we need to wait for completion, initialise the sfsync + * state here. + */ + if (flags & SF_SYNC) + sfs = sf_sync_alloc(flags & SF_SYNC); + + error = fo_sendfile(fp, sock_fd, hdr_uio, trl_uio, offset, + nbytes, sbytes, flags, compat ? SFK_COMPAT : 0, sfs, td); + + /* + * If appropriate, do the wait and free here. + */ + if (sfs != NULL) { + sf_sync_syscall_wait(sfs); + sf_sync_free(sfs); + } + + /* + * XXX Should we wait until the send has completed before freeing the source + * file handle? It's the previous behaviour, sure, but is it required? + * We've wired down the page references after all. + */ + fdrop(fp, td); + +out: + return (error); +} + static int do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) { struct sf_hdtr hdtr; struct uio *hdr_uio, *trl_uio; - struct file *fp; - cap_rights_t rights; int error; off_t sbytes; - struct sendfile_sync *sfs; /* * File offset must be positive. If it goes beyond EOF @@ -2007,7 +2055,6 @@ return (EINVAL); hdr_uio = trl_uio = NULL; - sfs = NULL; if (uap->hdtr != NULL) { error = copyin(uap->hdtr, &hdtr, sizeof(hdtr)); @@ -2022,46 +2069,12 @@ error = copyinuio(hdtr.trailers, hdtr.trl_cnt, &trl_uio); if (error != 0) goto out; - } } - AUDIT_ARG_FD(uap->fd); + error = _do_sendfile(td, uap->fd, uap->s, uap->flags, compat, + uap->offset, uap->nbytes, &sbytes, hdr_uio, trl_uio); - /* - * sendfile(2) can start at any offset within a file so we require - * CAP_READ+CAP_SEEK = CAP_PREAD. - */ - if ((error = fget_read(td, uap->fd, - cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) { - goto out; - } - - /* - * If we need to wait for completion, initialise the sfsync - * state here. - */ - if (uap->flags & SF_SYNC) - sfs = sf_sync_alloc(uap->flags & SF_SYNC); - - error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, uap->offset, - uap->nbytes, &sbytes, uap->flags, compat ? SFK_COMPAT : 0, sfs, td); - - /* - * If appropriate, do the wait and free here. - */ - if (sfs != NULL) { - sf_sync_syscall_wait(sfs); - sf_sync_free(sfs); - } - - /* - * XXX Should we wait until the send has completed before freeing the source - * file handle? It's the previous behaviour, sure, but is it required? - * We've wired down the page references after all. - */ - fdrop(fp, td); - if (uap->sbytes != NULL) { copyout(&sbytes, uap->sbytes, sizeof(off_t)); } Index: sys/sys/sf_base.h =================================================================== --- sys/sys/sf_base.h (revision 0) +++ sys/sys/sf_base.h (working copy) @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2013 Adrian Chadd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _SYS_SF_BASE_H_ +#define _SYS_SF_BASE_H_ + +extern int _do_sendfile(struct thread *, int src_fd, int sock_fd, int flags, + int compat, off_t offset, size_t nbytes, off_t *sbytes, + struct uio *hdr_uio, struct uio *trl_uio); + +#endif /* _SYS_SF_BASE_H_ */ Property changes on: sys/sys/sf_base.h ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property