Print this page
OS-3752 Increase IOV_MAX to at least 1024
OS-2834 ship lx brand

*** 22,32 **** /* All Rights Reserved */ /* * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright (c) 2014, Joyent, Inc. All rights reserved. */ #include <sys/types.h> #include <sys/sysmacros.h> #include <sys/param.h> --- 22,32 ---- /* All Rights Reserved */ /* * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2015, Joyent, Inc. All rights reserved. */ #include <sys/types.h> #include <sys/sysmacros.h> #include <sys/param.h>
*** 75,84 **** --- 75,85 ---- #include <sys/sunldi_impl.h> #include <sys/autoconf.h> #include <sys/policy.h> #include <sys/dld.h> #include <sys/zone.h> + #include <sys/limits.h> #include <c2/audit.h> /* * This define helps improve the readability of streams code while * still maintaining a very old streams performance enhancement. The
*** 983,998 **** * If this is the first time we're called by e.g. strread * only do the downcall if there is a deferred wakeup * (registered in sd_wakeq). */ struiod_t uiod; if (first) stp->sd_wakeq &= ~RSLEEP; ! (void) uiodup(uiop, &uiod.d_uio, uiod.d_iov, ! sizeof (uiod.d_iov) / sizeof (*uiod.d_iov)); uiod.d_mp = 0; /* * Mark that a thread is in rwnext on the read side * to prevent strrput from nacking ioctls immediately. * When the last concurrent rwnext returns --- 984,1007 ---- * If this is the first time we're called by e.g. strread * only do the downcall if there is a deferred wakeup * (registered in sd_wakeq). */ struiod_t uiod; + struct iovec buf[IOV_MAX_STACK]; + int iovlen = 0; if (first) stp->sd_wakeq &= ~RSLEEP; ! if (uiop->uio_iovcnt > IOV_MAX_STACK) { ! iovlen = uiop->uio_iovcnt * sizeof (iovec_t); ! uiod.d_iov = kmem_alloc(iovlen, KM_SLEEP); ! } else { ! uiod.d_iov = buf; ! } ! ! (void) uiodup(uiop, &uiod.d_uio, uiod.d_iov, uiop->uio_iovcnt); uiod.d_mp = 0; /* * Mark that a thread is in rwnext on the read side * to prevent strrput from nacking ioctls immediately. * When the last concurrent rwnext returns
*** 1027,1036 **** --- 1036,1047 ---- ASSERT(MUTEX_HELD(&stp->sd_lock)); if (error == 0 || error == EWOULDBLOCK) { if ((bp = uiod.d_mp) != NULL) { *errorp = 0; ASSERT(MUTEX_HELD(&stp->sd_lock)); + if (iovlen != 0) + kmem_free(uiod.d_iov, iovlen); return (bp); } error = 0; } else if (error == EINVAL) { /*
*** 1046,1057 **** --- 1057,1074 ---- */ error = 0; } else { *errorp = error; ASSERT(MUTEX_HELD(&stp->sd_lock)); + if (iovlen != 0) + kmem_free(uiod.d_iov, iovlen); return (NULL); } + + if (iovlen != 0) + kmem_free(uiod.d_iov, iovlen); + /* * Try a getq in case a rwnext() generated mblk * has bubbled up via strrput(). */ }
*** 2542,2551 **** --- 2559,2570 ---- static int strput(struct stdata *stp, mblk_t *mctl, struct uio *uiop, ssize_t *iosize, int b_flag, int pri, int flags) { struiod_t uiod; + struct iovec buf[IOV_MAX_STACK]; + int iovlen = 0; mblk_t *mp; queue_t *wqp = stp->sd_wrq; int error = 0; ssize_t count = *iosize;
*** 2633,2649 **** } mp->b_flag |= b_flag; mp->b_band = (uchar_t)pri; ! (void) uiodup(uiop, &uiod.d_uio, uiod.d_iov, ! sizeof (uiod.d_iov) / sizeof (*uiod.d_iov)); uiod.d_uio.uio_offset = 0; uiod.d_mp = mp; error = rwnext(wqp, &uiod); if (! uiod.d_mp) { uioskip(uiop, *iosize); return (error); } ASSERT(mp == uiod.d_mp); if (error == EINVAL) { /* --- 2652,2676 ---- } mp->b_flag |= b_flag; mp->b_band = (uchar_t)pri; ! if (uiop->uio_iovcnt > IOV_MAX_STACK) { ! iovlen = uiop->uio_iovcnt * sizeof (iovec_t); ! uiod.d_iov = (struct iovec *)kmem_alloc(iovlen, KM_SLEEP); ! } else { ! uiod.d_iov = buf; ! } ! ! (void) uiodup(uiop, &uiod.d_uio, uiod.d_iov, uiop->uio_iovcnt); uiod.d_uio.uio_offset = 0; uiod.d_mp = mp; error = rwnext(wqp, &uiod); if (! uiod.d_mp) { uioskip(uiop, *iosize); + if (iovlen != 0) + kmem_free(uiod.d_iov, iovlen); return (error); } ASSERT(mp == uiod.d_mp); if (error == EINVAL) { /*
*** 2657,2684 **** --- 2684,2719 ---- * so fall-back to putnext(). */ error = 0; } else { freemsg(mp); + if (iovlen != 0) + kmem_free(uiod.d_iov, iovlen); return (error); } /* Have to check canput before consuming data from the uio */ if (pri == 0) { if (!canputnext(wqp) && !(flags & MSG_IGNFLOW)) { freemsg(mp); + if (iovlen != 0) + kmem_free(uiod.d_iov, iovlen); return (EWOULDBLOCK); } } else { if (!bcanputnext(wqp, pri) && !(flags & MSG_IGNFLOW)) { freemsg(mp); + if (iovlen != 0) + kmem_free(uiod.d_iov, iovlen); return (EWOULDBLOCK); } } ASSERT(mp == uiod.d_mp); /* Copyin data from the uio */ if ((error = struioget(wqp, mp, &uiod, 0)) != 0) { freemsg(mp); + if (iovlen != 0) + kmem_free(uiod.d_iov, iovlen); return (error); } uioskip(uiop, *iosize); if (flags & MSG_IGNFLOW) { /*
*** 2691,2700 **** --- 2726,2737 ---- } else { stream_willservice(stp); putnext(wqp, mp); stream_runservice(stp); } + if (iovlen != 0) + kmem_free(uiod.d_iov, iovlen); return (0); } /* * Write attempts to break the write request into messages conforming
*** 3176,3185 **** --- 3213,3223 ---- case JTIMOM: /* Obsolete */ case JZOMBOOT: /* Obsolete */ case JAGENT: /* Obsolete */ case JTRUN: /* Obsolete */ case JXTPROTO: /* Obsolete */ + case TIOCSETLD: return (JCSETP); } return (JCGETP); }