summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2014-01-17 05:26:55 +0000
committeradrian <adrian@FreeBSD.org>2014-01-17 05:26:55 +0000
commitc46f73c7ae08f8eec4084f731b5c3c4c0fa42b19 (patch)
tree2ee74af347fde330acc3a30d52e45c03ba9e066e /sys/compat
parent9d7a5637e20993a9c0cc3fb858a18d0f8b49b310 (diff)
downloadFreeBSD-src-c46f73c7ae08f8eec4084f731b5c3c4c0fa42b19.zip
FreeBSD-src-c46f73c7ae08f8eec4084f731b5c3c4c0fa42b19.tar.gz
Implement a kqueue notification path for sendfile.
This fires off a kqueue note (of type sendfile) to the configured kqfd when the sendfile transaction has completed and the relevant memory backing the transaction is no longer in use by this transaction. This is analogous to SF_SYNC waiting for the mbufs to complete - except now you don't have to wait. Both SF_SYNC and SF_KQUEUE should work together, even if it doesn't necessarily make any practical sense. This is designed for use by applications which use backing cache/store files (eg Varnish) or POSIX shared memory (not sure anything is using it yet!) to know when a region of memory is free for re-use. Note it doesn't mark the region as free overall - only free from this transaction. The application developer still needs to track which ranges are in the process of being recycled and wait until all pending transactions are completed. TODO: * documentation, as always Sponsored by: Netflix, Inc.
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index c8681c6..719a057 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -1644,18 +1644,28 @@ struct sf_hdtr32 {
int trl_cnt;
};
+struct sf_hdtr_kq32 {
+ int kq_fd;
+ uint32_t kq_flags;
+ uint32_t kq_udata; /* 32-bit void ptr */
+ uint32_t kq_ident; /* 32-bit uintptr_t */
+};
+
static int
freebsd32_do_sendfile(struct thread *td,
struct freebsd32_sendfile_args *uap, int compat)
{
struct sf_hdtr32 hdtr32;
struct sf_hdtr hdtr;
+ struct sf_hdtr_kq32 hdtr_kq32;
+ struct sf_hdtr_kq hdtr_kq;
struct uio *hdr_uio, *trl_uio;
struct iovec32 *iov32;
off_t offset;
int error;
off_t sbytes;
struct sendfile_sync *sfs;
+ int do_kqueue = 0;
offset = PAIR32TO64(off_t, uap->offset);
if (offset < 0)
@@ -1687,10 +1697,32 @@ freebsd32_do_sendfile(struct thread *td,
if (error)
goto out;
}
+
+ /*
+ * If SF_KQUEUE is set, then we need to also copy in
+ * the kqueue data after the normal hdtr set and set do_kqueue=1.
+ */
+ if (uap->flags & SF_KQUEUE) {
+ error = copyin(((char *) uap->hdtr) + sizeof(hdtr32),
+ &hdtr_kq32,
+ sizeof(hdtr_kq32));
+ if (error != 0)
+ goto out;
+
+ /* 32->64 bit fields */
+ CP(hdtr_kq32, hdtr_kq, kq_fd);
+ CP(hdtr_kq32, hdtr_kq, kq_flags);
+ PTRIN_CP(hdtr_kq32, hdtr_kq, kq_udata);
+ CP(hdtr_kq32, hdtr_kq, kq_ident);
+ do_kqueue = 1;
+ }
}
+
+ /* Call sendfile */
+ /* XXX stack depth! */
error = _do_sendfile(td, uap->fd, uap->s, uap->flags, compat,
- offset, uap->nbytes, &sbytes, hdr_uio, trl_uio);
+ offset, uap->nbytes, &sbytes, hdr_uio, trl_uio, &hdtr_kq);
if (uap->sbytes != NULL)
copyout(&sbytes, uap->sbytes, sizeof(off_t));
OpenPOWER on IntegriCloud