diff options
author | adrian <adrian@FreeBSD.org> | 2013-12-01 03:53:21 +0000 |
---|---|---|
committer | adrian <adrian@FreeBSD.org> | 2013-12-01 03:53:21 +0000 |
commit | 86274dd213a33a0a9012f50b3209adc1d5a20bed (patch) | |
tree | e3a2f725c4c9350bd7a0727c06a7497a8c4c68e3 /sys/compat | |
parent | 36d4a7a0b7b17cce6f348427fa01f9ed8d78bba0 (diff) | |
download | FreeBSD-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.c | 20 |
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)); |