summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mooney <pmooney@pfmooney.com>2016-03-16 22:38:25 +0000
committerPatrick Mooney <pmooney@pfmooney.com>2016-03-17 16:02:33 +0000
commit3441ff0a45b5e58d3773f3be389212818ba238ce (patch)
tree38bfaf862bc448945c91d30c2e3e72ace12cc894
parente0e2e6f457fdf76f365898cb7e350cc028d410e4 (diff)
downloadillumos-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_skiplist4
-rw-r--r--usr/src/uts/common/brand/lx/syscall/lx_fcntl.c84
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));
}