Date: Thu, 9 Jan 2014 00:11:15 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r260461 - in head/sys: compat/freebsd32 kern sys Message-ID: <201401090011.s090BFgr037177@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Thu Jan 9 00:11:14 2014 New Revision: 260461 URL: http://svnweb.freebsd.org/changeset/base/260461 Log: Refactor out the common sendfile code from the do_sendfile() and the compat32 sendfile syscall. Sponsored by: Netflix, Inc. Added: head/sys/sys/sf_base.h (contents, props changed) Modified: head/sys/compat/freebsd32/freebsd32_misc.c head/sys/kern/uipc_syscalls.c Modified: head/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- head/sys/compat/freebsd32/freebsd32_misc.c Wed Jan 8 23:09:02 2014 (r260460) +++ head/sys/compat/freebsd32/freebsd32_misc.c Thu Jan 9 00:11:14 2014 (r260461) @@ -86,6 +86,7 @@ __FBSDID("$FreeBSD$"); #include <sys/condvar.h> #include <sys/sf_buf.h> #include <sys/sf_sync.h> +#include <sys/sf_base.h> #ifdef INET #include <netinet/in.h> @@ -1651,8 +1652,6 @@ freebsd32_do_sendfile(struct thread *td, 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 @@ freebsd32_do_sendfile(struct thread *td, } } - 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)); Modified: head/sys/kern/uipc_syscalls.c ============================================================================== --- head/sys/kern/uipc_syscalls.c Wed Jan 8 23:09:02 2014 (r260460) +++ head/sys/kern/uipc_syscalls.c Thu Jan 9 00:11:14 2014 (r260461) @@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$"); #include <sys/rwlock.h> #include <sys/sf_buf.h> #include <sys/sf_sync.h> +#include <sys/sf_base.h> #include <sys/sysent.h> #include <sys/socket.h> #include <sys/socketvar.h> @@ -1988,51 +1989,23 @@ sys_sendfile(struct thread *td, struct s return (do_sendfile(td, uap, 0)); } -static int -do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) +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) { - struct sf_hdtr hdtr; - struct uio *hdr_uio, *trl_uio; - struct file *fp; cap_rights_t rights; + struct sendfile_sync *sfs = NULL; + struct file *fp; int error; - off_t sbytes; - struct sendfile_sync *sfs; - /* - * File offset must be positive. If it goes beyond EOF - * we send only the header/trailer and no payload data. - */ - if (uap->offset < 0) - return (EINVAL); - - hdr_uio = trl_uio = NULL; - sfs = NULL; - - if (uap->hdtr != NULL) { - error = copyin(uap->hdtr, &hdtr, sizeof(hdtr)); - if (error != 0) - goto out; - if (hdtr.headers != NULL) { - error = copyinuio(hdtr.headers, hdtr.hdr_cnt, &hdr_uio); - if (error != 0) - goto out; - } - if (hdtr.trailers != NULL) { - error = copyinuio(hdtr.trailers, hdtr.trl_cnt, &trl_uio); - if (error != 0) - goto out; - - } - } - - AUDIT_ARG_FD(uap->fd); + 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, uap->fd, + if ((error = fget_read(td, src_fd, cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) { goto out; } @@ -2041,11 +2014,11 @@ do_sendfile(struct thread *td, struct se * 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); + if (flags & SF_SYNC) + sfs = sf_sync_alloc(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); + 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. @@ -2062,6 +2035,46 @@ do_sendfile(struct thread *td, struct se */ 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; + int error; + off_t sbytes; + + /* + * File offset must be positive. If it goes beyond EOF + * we send only the header/trailer and no payload data. + */ + if (uap->offset < 0) + return (EINVAL); + + hdr_uio = trl_uio = NULL; + + if (uap->hdtr != NULL) { + error = copyin(uap->hdtr, &hdtr, sizeof(hdtr)); + if (error != 0) + goto out; + if (hdtr.headers != NULL) { + error = copyinuio(hdtr.headers, hdtr.hdr_cnt, &hdr_uio); + if (error != 0) + goto out; + } + if (hdtr.trailers != NULL) { + error = copyinuio(hdtr.trailers, hdtr.trl_cnt, &trl_uio); + if (error != 0) + goto out; + } + } + + error = _do_sendfile(td, uap->fd, uap->s, uap->flags, compat, + uap->offset, uap->nbytes, &sbytes, hdr_uio, trl_uio); + if (uap->sbytes != NULL) { copyout(&sbytes, uap->sbytes, sizeof(off_t)); } Added: head/sys/sys/sf_base.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/sys/sf_base.h Thu Jan 9 00:11:14 2014 (r260461) @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2013 Adrian Chadd <adrian@FreeBSD.org> + * 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_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401090011.s090BFgr037177>