diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2017-09-05 14:42:44 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2017-09-05 14:43:38 +0000 |
commit | 58cb9430032e4f58eaafab0be2b42662cb3f1180 (patch) | |
tree | 94ad81d36930229173132452ac1a0ab608ca0fbd | |
parent | 9105a020d63cb56f2be32de07d869c429cf3d4a8 (diff) | |
download | illumos-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.c | 33 | ||||
-rw-r--r-- | usr/src/uts/common/fs/fifofs/fifosubr.c | 12 | ||||
-rw-r--r-- | usr/src/uts/common/fs/fifofs/fifovnops.c | 15 | ||||
-rw-r--r-- | usr/src/uts/common/sys/fs/fifonode.h | 12 |
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; |