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 <adr...@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_ */
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to