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);
  }