diff options
author | Patrick Mooney <pmooney@pfmooney.com> | 2016-03-16 22:38:25 +0000 |
---|---|---|
committer | Patrick Mooney <pmooney@pfmooney.com> | 2016-03-17 16:02:33 +0000 |
commit | 3441ff0a45b5e58d3773f3be389212818ba238ce (patch) | |
tree | 38bfaf862bc448945c91d30c2e3e72ace12cc894 | |
parent | e0e2e6f457fdf76f365898cb7e350cc028d410e4 (diff) | |
download | illumos-joyent-3441ff0a45b5e58d3773f3be389212818ba238ce.tar.gz |
OS-5249 lxbrand fcntl(F_SETPIPE_SZ) needed by MapR
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
-rw-r--r-- | usr/src/lib/brand/lx/testing/ltp_skiplist | 4 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/syscall/lx_fcntl.c | 84 |
2 files changed, 82 insertions, 6 deletions
diff --git a/usr/src/lib/brand/lx/testing/ltp_skiplist b/usr/src/lib/brand/lx/testing/ltp_skiplist index 66d6eae2b8..5a8bd35a16 100644 --- a/usr/src/lib/brand/lx/testing/ltp_skiplist +++ b/usr/src/lib/brand/lx/testing/ltp_skiplist @@ -9,7 +9,7 @@ # http://www.illumos.org/license/CDDL. # -# Copyright 2015, Joyent, Inc. +# Copyright 2016 Joyent, Inc. # Broken tests poll02 # OS-3997 @@ -148,8 +148,6 @@ fcntl25 fcntl25_64 fcntl26 fcntl26_64 -fcntl30 -fcntl30_64 fcntl31 fcntl31_64 fcntl32 diff --git a/usr/src/uts/common/brand/lx/syscall/lx_fcntl.c b/usr/src/uts/common/brand/lx/syscall/lx_fcntl.c index 1baaa6d48b..2699b9bac7 100644 --- a/usr/src/uts/common/brand/lx/syscall/lx_fcntl.c +++ b/usr/src/uts/common/brand/lx/syscall/lx_fcntl.c @@ -10,7 +10,7 @@ */ /* - * Copyright 2015 Joyent, Inc. + * Copyright 2016 Joyent, Inc. */ #include <sys/systm.h> @@ -26,6 +26,9 @@ #include <sys/lx_fcntl.h> #include <sys/lx_misc.h> #include <sys/lx_socket.h> +#include <sys/fs/fifonode.h> +#include <sys/strsubr.h> +#include <sys/stream.h> extern int fcntl(int, int, intptr_t); extern int flock_check(vnode_t *, flock64_t *, offset_t, offset_t); @@ -191,6 +194,78 @@ lx_fcntl_setfl(int fd, ulong_t arg) return (fcntl(fd, F_SETFL, new_arg)); } +/* The default unprivileged limit in Linux is 1MB */ +static int lx_pipe_max_size = 1048576; + +static int +lx_fcntl_pipesz(int fd, int cmd, ulong_t arg) +{ + file_t *fp; + vnode_t *vp; + stdata_t *str; + int err = 0, res = 0; + + if ((fp = getf(fd)) == NULL) { + return (set_errno(EBADF)); + } + vp = fp->f_vnode; + if (vp->v_type != VFIFO || vp->v_op != fifo_vnodeops) { + err = EBADF; + goto out; + } + VERIFY((str = vp->v_stream) != NULL); + + if (cmd == LX_F_SETPIPE_SZ) { + stdata_t *mate; + intptr_t val = arg; + + if (val < PAGESIZE || val > lx_pipe_max_size) { + err = EINVAL; + goto out; + } + if (!STRMATED(str)) { + err = strqset(RD(str->sd_wrq), QHIWAT, 0, val); + goto out; + } + + /* + * Ensure consistent order so the set operation is always + * attempted on the "higher" stream first. + */ + if (str > str->sd_mate) { + VERIFY((mate = str->sd_mate) != NULL); + } else { + mate = str; + VERIFY((str = mate->sd_mate) != NULL); + } + + /* + * While it is unfortunate that an error could occur for the + * latter half of the stream pair, there is little to be done + * about it aside from reporting the failure. + */ + if ((err = strqset(RD(str->sd_wrq), QHIWAT, 0, val)) != 0) { + goto out; + } + err = strqset(RD(mate->sd_wrq), QHIWAT, 0, val); + } else if (cmd == LX_F_GETPIPE_SZ) { + size_t val; + + err = strqget(RD(str->sd_wrq), QHIWAT, 0, &val); + res = val; + } else { + /* NOTREACHED */ + ASSERT(0); + } + +out: + releasef(fd); + if (err != 0) { + return (set_errno(err)); + } + return (res); +} + static int lx_fcntl_common(int fd, int cmd, ulong_t arg) { @@ -213,8 +288,6 @@ lx_fcntl_common(int fd, int cmd, ulong_t arg) case LX_F_GETLEASE: case LX_F_NOTIFY: case LX_F_CANCELLK: - case LX_F_SETPIPE_SZ: - case LX_F_GETPIPE_SZ: { char buf[80]; @@ -302,6 +375,11 @@ lx_fcntl_common(int fd, int cmd, ulong_t arg) rc = pid; break; + case LX_F_SETPIPE_SZ: + case LX_F_GETPIPE_SZ: + rc = lx_fcntl_pipesz(fd, cmd, arg); + break; + default: return (set_errno(EINVAL)); } |