summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2017-09-05 14:42:44 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2017-09-05 14:43:38 +0000
commit58cb9430032e4f58eaafab0be2b42662cb3f1180 (patch)
tree94ad81d36930229173132452ac1a0ab608ca0fbd
parent9105a020d63cb56f2be32de07d869c429cf3d4a8 (diff)
downloadillumos-joyent-58cb9430032e4f58eaafab0be2b42662cb3f1180.tar.gz
OS-6275 lx pipe buffer is too small
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com> Approved by: Jason King <jason.king@joyent.com>
-rw-r--r--usr/src/uts/common/brand/lx/syscall/lx_pipe.c33
-rw-r--r--usr/src/uts/common/fs/fifofs/fifosubr.c12
-rw-r--r--usr/src/uts/common/fs/fifofs/fifovnops.c15
-rw-r--r--usr/src/uts/common/sys/fs/fifonode.h12
4 files changed, 46 insertions, 26 deletions
diff --git a/usr/src/uts/common/brand/lx/syscall/lx_pipe.c b/usr/src/uts/common/brand/lx/syscall/lx_pipe.c
index d6c8f1d274..96959e40df 100644
--- a/usr/src/uts/common/brand/lx/syscall/lx_pipe.c
+++ b/usr/src/uts/common/brand/lx/syscall/lx_pipe.c
@@ -65,7 +65,7 @@ lx_pipe_setsz(stdata_t *str, uint_t size, boolean_t is_init)
stdata_t *mate;
lx_zone_data_t *lxzd = ztolxzd(curzone);
uint_t max_size = lxzd->lxzd_pipe_max_sz;
-
+ fifonode_t *fnp1, *fnp2;
size = P2ROUNDUP(size, PAGESIZE);
if (size == 0) {
@@ -94,7 +94,14 @@ lx_pipe_setsz(stdata_t *str, uint_t size, boolean_t is_init)
}
if (!STRMATED(str)) {
- return (strqset(RD(str->sd_wrq), QHIWAT, 0, (intptr_t)size));
+ err = strqset(RD(str->sd_wrq), QHIWAT, 0, (intptr_t)size);
+ if (err == 0) {
+ fnp1 = VTOF(str->sd_vnode);
+ mutex_enter(&fnp1->fn_lock->flk_lock);
+ fnp1->fn_hiwat = size;
+ mutex_exit(&fnp1->fn_lock->flk_lock);
+ }
+ return (err);
}
/*
@@ -116,6 +123,28 @@ lx_pipe_setsz(stdata_t *str, uint_t size, boolean_t is_init)
if ((err = strqset(RD(str->sd_wrq), QHIWAT, 0, (intptr_t)size)) == 0) {
err = strqset(RD(mate->sd_wrq), QHIWAT, 0, (intptr_t)size);
}
+
+ if (err == 0) {
+ fnp1 = VTOF(str->sd_vnode);
+ fnp2 = VTOF(str->sd_mate->sd_vnode);
+
+ /*
+ * See fnode_constructor. Both sides should have the same
+ * lock. We expect our callers to ensure that the vnodes
+ * are VFIFO and have v_op == fifovnops.
+ */
+ ASSERT(str->sd_vnode->v_type == VFIFO);
+ ASSERT(str->sd_mate->sd_vnode->v_type == VFIFO);
+ ASSERT(fnp1->fn_lock == fnp2->fn_lock);
+
+ mutex_enter(&fnp1->fn_lock->flk_lock);
+
+ fnp1->fn_hiwat = size;
+ fnp2->fn_hiwat = size;
+
+ mutex_exit(&fnp1->fn_lock->flk_lock);
+ }
+
return (err);
}
diff --git a/usr/src/uts/common/fs/fifofs/fifosubr.c b/usr/src/uts/common/fs/fifofs/fifosubr.c
index 56204c6741..a908f91267 100644
--- a/usr/src/uts/common/fs/fifofs/fifosubr.c
+++ b/usr/src/uts/common/fs/fifofs/fifosubr.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
*/
/*
@@ -61,7 +62,6 @@
#if FIFODEBUG
int Fifo_fastmode = 1; /* pipes/fifos will be opened in fast mode */
int Fifo_verbose = 0; /* msg when switching out of fast mode */
-int Fifohiwat = FIFOHIWAT; /* Modifiable FIFO high water mark */
#endif
/*
@@ -196,6 +196,7 @@ fnode_constructor(void *buf, void *cdrarg, int kmflags)
fnp->fn_dest = fnp;
fnp->fn_mp = NULL;
fnp->fn_count = 0;
+ fnp->fn_hiwat = FIFOHIWAT;
fnp->fn_rsynccnt = 0;
fnp->fn_wsynccnt = 0;
fnp->fn_wwaitcnt = 0;
@@ -388,11 +389,7 @@ fifoinit(int fstype, char *name)
pipe_constructor, pipe_destructor, NULL,
(void *)(sizeof (fifodata_t)), NULL, 0);
-#if FIFODEBUG
- if (Fifohiwat < FIFOHIWAT)
- Fifohiwat = FIFOHIWAT;
-#endif /* FIFODEBUG */
- fifo_strdata.qi_minfo->mi_hiwat = Fifohiwat;
+ fifo_strdata.qi_minfo->mi_hiwat = FIFOHIWAT;
return (0);
}
@@ -1164,7 +1161,8 @@ fifo_wakewriter(fifonode_t *fn_dest, fifolock_t *fn_lock)
int fn_dflag = fn_dest->fn_flag;
ASSERT(MUTEX_HELD(&fn_lock->flk_lock));
- ASSERT(fn_dest->fn_dest->fn_count < Fifohiwat);
+ ASSERT(fn_dest->fn_dest->fn_count < fn_dest->fn_dest->fn_hiwat);
+
if ((fn_dflag & FIFOWANTW)) {
cv_broadcast(&fn_dest->fn_wait_cv);
}
diff --git a/usr/src/uts/common/fs/fifofs/fifovnops.c b/usr/src/uts/common/fs/fifofs/fifovnops.c
index ef8d76e8e8..f11535dd83 100644
--- a/usr/src/uts/common/fs/fifofs/fifovnops.c
+++ b/usr/src/uts/common/fs/fifofs/fifovnops.c
@@ -28,7 +28,7 @@
*/
/*
- * Copyright 2015, Joyent, Inc.
+ * Copyright 2017, Joyent, Inc.
* Copyright (c) 2017 by Delphix. All rights reserved.
*/
@@ -787,11 +787,11 @@ trywake:
/*
* wake up any blocked writers, processes
* sleeping on POLLWRNORM, or processes waiting for SIGPOLL
- * Note: checking for fn_count < Fifohiwat emulates
+ * Note: checking for fn_count < fn_hiwat emulates
* STREAMS functionality when low water mark is 0
*/
if (fn_dest->fn_flag & (FIFOWANTW | FIFOHIWATW) &&
- fnp->fn_count < Fifohiwat) {
+ fnp->fn_count < fn_dest->fn_hiwat) {
fifo_wakewriter(fn_dest, fn_lock);
}
goto done;
@@ -904,7 +904,7 @@ fifo_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *crp,
/*
* check to make sure we are not over high water mark
*/
- while (fn_dest->fn_count >= Fifohiwat) {
+ while (fn_dest->fn_count >= fn_dest->fn_hiwat) {
/*
* Indicate that we have gone over high
* water mark
@@ -962,7 +962,7 @@ fifo_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *crp,
* then we must break the message up into PIPE_BUF
* chunks to stay compliant with STREAMS
*/
- if (uiop->uio_resid + fn_dest->fn_count > Fifohiwat)
+ if (uiop->uio_resid + fn_dest->fn_count > fn_dest->fn_hiwat)
size = MIN(uiop->uio_resid, PIPE_BUF);
else
size = uiop->uio_resid;
@@ -1198,7 +1198,8 @@ fifo_fastioctl(vnode_t *vp, int cmd, intptr_t arg, int mode, cred_t *cr,
if (arg != 0) {
goto turn_fastoff;
}
- *rvalp = (fnp->fn_dest->fn_count < Fifohiwat) ? 1 : 0;
+ *rvalp = (fnp->fn_dest->fn_count < fnp->fn_dest->fn_hiwat) ?
+ 1 : 0;
mutex_exit(&fn_lock->flk_lock);
return (0);
@@ -1817,7 +1818,7 @@ fifo_poll(vnode_t *vp, short events, int anyyet, short *reventsp,
retevents = POLLHUP;
} else if (events & (POLLWRNORM | POLLWRBAND)) {
if (events & POLLWRNORM) {
- if (fn_dest->fn_count < Fifohiwat)
+ if (fn_dest->fn_count < fn_dest->fn_hiwat)
retevents = POLLWRNORM;
else
fnp->fn_flag |= FIFOHIWATW;
diff --git a/usr/src/uts/common/sys/fs/fifonode.h b/usr/src/uts/common/sys/fs/fifonode.h
index d8b158ce3c..e1b9fe872c 100644
--- a/usr/src/uts/common/sys/fs/fifonode.h
+++ b/usr/src/uts/common/sys/fs/fifonode.h
@@ -21,6 +21,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2017 Joyent, Inc.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -83,6 +84,7 @@ struct fifonode {
struct msgb *fn_tail; /* last message to read */
fifolock_t *fn_lock; /* pointer to per fifo lock */
uint_t fn_count; /* Number of bytes on fn_mp */
+ uint_t fn_hiwat; /* pipe (fifofast) high water */
kcondvar_t fn_wait_cv; /* fifo conditional variable */
ushort_t fn_wcnt; /* number of writers */
ushort_t fn_rcnt; /* number of readers */
@@ -147,16 +149,6 @@ typedef struct fifodata {
#if defined(_KERNEL)
-/*
- * Fifohiwat defined as a variable is to allow tuning of the high
- * water mark if needed. It is not meant to be released.
- */
-#if FIFODEBUG
-extern int Fifohiwat;
-#else /* FIFODEBUG */
-#define Fifohiwat FIFOHIWAT
-#endif /* FIFODEBUG */
-
extern struct vnodeops *fifo_vnodeops;
extern const struct fs_operation_def fifo_vnodeops_template[];
extern struct kmem_cache *fnode_cache;