svn commit: r260461 - in head/sys: compat/freebsd32 kern sys
Adrian Chadd
adrian at FreeBSD.org
Thu Jan 9 00:11:16 UTC 2014
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 at 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_ */
More information about the svn-src-all
mailing list