summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2013-12-01 03:53:21 +0000
committeradrian <adrian@FreeBSD.org>2013-12-01 03:53:21 +0000
commit86274dd213a33a0a9012f50b3209adc1d5a20bed (patch)
treee3a2f725c4c9350bd7a0727c06a7497a8c4c68e3 /sys/compat
parent36d4a7a0b7b17cce6f348427fa01f9ed8d78bba0 (diff)
downloadFreeBSD-src-86274dd213a33a0a9012f50b3209adc1d5a20bed.zip
FreeBSD-src-86274dd213a33a0a9012f50b3209adc1d5a20bed.tar.gz
Migrate the sendfile_sync structure into a public(ish) API in preparation
for extending and reusing it. The sendfile_sync wrapper is mostly just a "mbuf transaction" wrapper, used to indicate that the backing store for a group of mbufs has completed. It's only being used by sendfile for now and it's only implementing a sleep/wakeup rendezvous. However, there are other potential signaling paths (kqueue) and other potential uses (socket zero-copy write) where the same mechanism would also be useful. So, with that in mind: * extract the sendfile_sync code out into sf_sync_*() methods * teach the sf_sync_alloc method about the current config flag - it will eventually know about kqueue. * move the sendfile_sync code out of do_sendfile() - the only thing it now knows about is the sfs pointer. The guts of the sync rendezvous (setup, rendezvous/wait, free) is now done in the syscall wrapper. * .. and teach the 32-bit compat sendfile call the same. This should be a no-op. It's primarily preparation work for teaching the sendfile_sync about kqueue notification. Tested: * Peter Holm's sendfile stress / regression scripts Sponsored by: Netflix, Inc.
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 0703fd3..3b26745 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -83,6 +83,9 @@ __FBSDID("$FreeBSD$");
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
+#include <sys/condvar.h>
+#include <sys/sf_buf.h>
+#include <sys/sf_sync.h>
#ifdef INET
#include <netinet/in.h>
@@ -1653,12 +1656,14 @@ freebsd32_do_sendfile(struct thread *td,
off_t offset;
int error;
off_t sbytes;
+ struct sendfile_sync *sfs;
offset = PAIR32TO64(off_t, uap->offset);
if (offset < 0)
return (EINVAL);
hdr_uio = trl_uio = NULL;
+ sfs = NULL;
if (uap->hdtr != NULL) {
error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32));
@@ -1692,8 +1697,21 @@ freebsd32_do_sendfile(struct thread *td,
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, td);
+ 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));
OpenPOWER on IntegriCloud