1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  22 /*        All rights reserved.          */
  23 
  24 
  25 /*
  26  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  27  * Use is subject to license terms.
  28  */
  29 
  30 /*
  31  * Copyright 2015, Joyent, Inc.
  32  */
  33 
  34 /*
  35  * FIFOFS file system vnode operations.  This file system
  36  * type supports STREAMS-based pipes and FIFOs.
  37  */
  38 #include <sys/types.h>
  39 #include <sys/param.h>
  40 #include <sys/systm.h>
  41 #include <sys/sysmacros.h>
  42 #include <sys/cred.h>
  43 #include <sys/errno.h>
  44 #include <sys/time.h>
  45 #include <sys/file.h>
  46 #include <sys/fcntl.h>
  47 #include <sys/kmem.h>
  48 #include <sys/uio.h>
  49 #include <sys/vfs.h>
  50 #include <sys/vnode.h>
  51 #include <sys/vfs_opreg.h>
  52 #include <sys/pathname.h>
  53 #include <sys/signal.h>
  54 #include <sys/user.h>
  55 #include <sys/strsubr.h>
  56 #include <sys/stream.h>
  57 #include <sys/strsun.h>
  58 #include <sys/strredir.h>
  59 #include <sys/fs/fifonode.h>
  60 #include <sys/fs/namenode.h>
  61 #include <sys/stropts.h>
  62 #include <sys/proc.h>
  63 #include <sys/unistd.h>
  64 #include <sys/debug.h>
  65 #include <fs/fs_subr.h>
  66 #include <sys/filio.h>
  67 #include <sys/termio.h>
  68 #include <sys/ddi.h>
  69 #include <sys/vtrace.h>
  70 #include <sys/policy.h>
  71 #include <sys/tsol/label.h>
  72 
  73 /*
  74  * Define the routines/data structures used in this file.
  75  */
  76 static int fifo_read(vnode_t *, uio_t *, int, cred_t *, caller_context_t *);
  77 static int fifo_write(vnode_t *, uio_t *, int, cred_t *, caller_context_t *);
  78 static int fifo_getattr(vnode_t *, vattr_t *, int, cred_t *,
  79         caller_context_t *);
  80 static int fifo_setattr(vnode_t *, vattr_t *, int, cred_t *,
  81         caller_context_t *);
  82 static int fifo_realvp(vnode_t *, vnode_t **, caller_context_t *);
  83 static int fifo_access(vnode_t *, int, int, cred_t *, caller_context_t *);
  84 static int fifo_create(struct vnode *, char *, vattr_t *, enum vcexcl,
  85     int, struct vnode **, struct cred *, int, caller_context_t *,
  86     vsecattr_t *);
  87 static int fifo_fid(vnode_t *, fid_t *, caller_context_t *);
  88 static int fifo_fsync(vnode_t *, int, cred_t *, caller_context_t *);
  89 static int fifo_seek(vnode_t *, offset_t, offset_t *, caller_context_t *);
  90 static int fifo_ioctl(vnode_t *, int, intptr_t, int, cred_t *, int *,
  91         caller_context_t *);
  92 static int fifo_fastioctl(vnode_t *, int, intptr_t, int, cred_t *, int *);
  93 static int fifo_strioctl(vnode_t *, int, intptr_t, int, cred_t *, int *);
  94 static int fifo_poll(vnode_t *, short, int, short *, pollhead_t **,
  95         caller_context_t *);
  96 static int fifo_pathconf(vnode_t *, int, ulong_t *, cred_t *,
  97         caller_context_t *);
  98 static void fifo_inactive(vnode_t *, cred_t *, caller_context_t *);
  99 static int fifo_rwlock(vnode_t *, int, caller_context_t *);
 100 static void fifo_rwunlock(vnode_t *, int, caller_context_t *);
 101 static int fifo_setsecattr(struct vnode *, vsecattr_t *, int, struct cred *,
 102         caller_context_t *);
 103 static int fifo_getsecattr(struct vnode *, vsecattr_t *, int, struct cred *,
 104         caller_context_t *);
 105 
 106 /* functions local to this file */
 107 static boolean_t fifo_stayfast_enter(fifonode_t *);
 108 static void fifo_stayfast_exit(fifonode_t *);
 109 
 110 /*
 111  * Define the data structures external to this file.
 112  */
 113 extern  dev_t   fifodev;
 114 extern struct qinit fifo_stwdata;
 115 extern struct qinit fifo_strdata;
 116 extern kmutex_t ftable_lock;
 117 
 118 struct  streamtab fifoinfo = { &fifo_strdata, &fifo_stwdata, NULL, NULL };
 119 
 120 struct vnodeops *fifo_vnodeops;
 121 
 122 const fs_operation_def_t fifo_vnodeops_template[] = {
 123         VOPNAME_OPEN,           { .vop_open = fifo_open },
 124         VOPNAME_CLOSE,          { .vop_close = fifo_close },
 125         VOPNAME_READ,           { .vop_read = fifo_read },
 126         VOPNAME_WRITE,          { .vop_write = fifo_write },
 127         VOPNAME_IOCTL,          { .vop_ioctl = fifo_ioctl },
 128         VOPNAME_GETATTR,        { .vop_getattr = fifo_getattr },
 129         VOPNAME_SETATTR,        { .vop_setattr = fifo_setattr },
 130         VOPNAME_ACCESS,         { .vop_access = fifo_access },
 131         VOPNAME_CREATE,         { .vop_create = fifo_create },
 132         VOPNAME_FSYNC,          { .vop_fsync = fifo_fsync },
 133         VOPNAME_INACTIVE,       { .vop_inactive = fifo_inactive },
 134         VOPNAME_FID,            { .vop_fid = fifo_fid },
 135         VOPNAME_RWLOCK,         { .vop_rwlock = fifo_rwlock },
 136         VOPNAME_RWUNLOCK,       { .vop_rwunlock = fifo_rwunlock },
 137         VOPNAME_SEEK,           { .vop_seek = fifo_seek },
 138         VOPNAME_REALVP,         { .vop_realvp = fifo_realvp },
 139         VOPNAME_POLL,           { .vop_poll = fifo_poll },
 140         VOPNAME_PATHCONF,       { .vop_pathconf = fifo_pathconf },
 141         VOPNAME_DISPOSE,        { .error = fs_error },
 142         VOPNAME_SETSECATTR,     { .vop_setsecattr = fifo_setsecattr },
 143         VOPNAME_GETSECATTR,     { .vop_getsecattr = fifo_getsecattr },
 144         NULL,                   NULL
 145 };
 146 
 147 /*
 148  * Return the fifoinfo structure.
 149  */
 150 struct streamtab *
 151 fifo_getinfo()
 152 {
 153         return (&fifoinfo);
 154 }
 155 
 156 /*
 157  * Trusted Extensions enforces a restrictive policy for
 158  * writing via cross-zone named pipes. A privileged global
 159  * zone process may expose a named pipe by loopback mounting
 160  * it from a lower-level zone to a higher-level zone. The
 161  * kernel-enforced mount policy for lofs mounts ensures
 162  * that such mounts are read-only in the higher-level
 163  * zone. But this is not sufficient to prevent writing
 164  * down via fifos.  This function prevents writing down
 165  * by comparing the zone of the process which is requesting
 166  * write access with the zone owning the named pipe rendezvous.
 167  * For write access the zone of the named pipe must equal the
 168  * zone of the writing process. Writing up is possible since
 169  * the named pipe can be opened for read by a process in a
 170  * higher level zone.
 171  *
 172  * An exception is made for the global zone to support trusted
 173  * processes which enforce their own data flow policies.
 174  */
 175 static boolean_t
 176 tsol_fifo_access(vnode_t *vp, int flag, cred_t *crp)
 177 {
 178         fifonode_t      *fnp = VTOF(vp);
 179 
 180         if (is_system_labeled() &&
 181             (flag & FWRITE) &&
 182             (!(fnp->fn_flag & ISPIPE))) {
 183                 zone_t  *proc_zone;
 184 
 185                 proc_zone = crgetzone(crp);
 186                 if (proc_zone != global_zone) {
 187                         char            vpath[MAXPATHLEN];
 188                         zone_t          *fifo_zone;
 189 
 190                         /*
 191                          * Get the pathname and use it to find
 192                          * the zone of the fifo.
 193                          */
 194                         if (vnodetopath(rootdir, vp, vpath, sizeof (vpath),
 195                             kcred) == 0) {
 196                                 fifo_zone = zone_find_by_path(vpath);
 197                                 zone_rele(fifo_zone);
 198 
 199                                 if (fifo_zone != global_zone &&
 200                                     fifo_zone != proc_zone) {
 201                                         return (B_FALSE);
 202                                 }
 203                         } else {
 204                                 return (B_FALSE);
 205                         }
 206                 }
 207         }
 208         return (B_TRUE);
 209 }
 210 
 211 /*
 212  * Open and stream a FIFO.
 213  * If this is the first open of the file (FIFO is not streaming),
 214  * initialize the fifonode and attach a stream to the vnode.
 215  *
 216  * Each end of a fifo must be synchronized with the other end.
 217  * If not, the mated end may complete an open, I/O, close sequence
 218  * before the end waiting in open ever wakes up.
 219  * Note: namefs pipes come through this routine too.
 220  */
 221 int
 222 fifo_open(vnode_t **vpp, int flag, cred_t *crp, caller_context_t *ct)
 223 {
 224         vnode_t         *vp             = *vpp;
 225         fifonode_t      *fnp            = VTOF(vp);
 226         fifolock_t      *fn_lock        = fnp->fn_lock;
 227         int             error;
 228 
 229         ASSERT(vp->v_type == VFIFO);
 230         ASSERT(vn_matchops(vp, fifo_vnodeops));
 231 
 232         if (!tsol_fifo_access(vp, flag, crp))
 233                 return (EACCES);
 234 
 235         mutex_enter(&fn_lock->flk_lock);
 236         /*
 237          * If we are the first reader, wake up any writers that
 238          * may be waiting around.  wait for all of them to
 239          * wake up before proceeding (i.e. fn_wsynccnt == 0)
 240          */
 241         if (flag & FREAD) {
 242                 fnp->fn_rcnt++;              /* record reader present */
 243                 if (! (fnp->fn_flag & ISPIPE))
 244                         fnp->fn_rsynccnt++;  /* record reader in open */
 245         }
 246 
 247         /*
 248          * If we are the first writer, wake up any readers that
 249          * may be waiting around.  wait for all of them to
 250          * wake up before proceeding (i.e. fn_rsynccnt == 0)
 251          */
 252         if (flag & FWRITE) {
 253                 fnp->fn_wcnt++;              /* record writer present */
 254                 if (! (fnp->fn_flag & ISPIPE))
 255                         fnp->fn_wsynccnt++;  /* record writer in open */
 256         }
 257         /*
 258          * fifo_stropen will take care of twisting the queues on the first
 259          * open.  The 1 being passed in means twist the queues on the first
 260          * open.
 261          */
 262         error = fifo_stropen(vpp, flag, crp, 1, 1);
 263         /*
 264          * fifo_stropen() could have replaced vpp
 265          * since fifo's are the only thing we need to sync up,
 266          * everything else just returns;
 267          * Note: don't need to hold lock since ISPIPE can't change
 268          * and both old and new vp need to be pipes
 269          */
 270         ASSERT(MUTEX_HELD(&VTOF(*vpp)->fn_lock->flk_lock));
 271         if (fnp->fn_flag & ISPIPE) {
 272                 ASSERT(VTOF(*vpp)->fn_flag & ISPIPE);
 273                 ASSERT(VTOF(*vpp)->fn_rsynccnt == 0);
 274                 ASSERT(VTOF(*vpp)->fn_rsynccnt == 0);
 275                 /*
 276                  * XXX note: should probably hold locks, but
 277                  * These values should not be changing
 278                  */
 279                 ASSERT(fnp->fn_rsynccnt == 0);
 280                 ASSERT(fnp->fn_wsynccnt == 0);
 281                 mutex_exit(&VTOF(*vpp)->fn_lock->flk_lock);
 282                 return (error);
 283         }
 284         /*
 285          * vp can't change for FIFOS
 286          */
 287         ASSERT(vp == *vpp);
 288         /*
 289          * If we are opening for read (or writer)
 290          *   indicate that the reader (or writer) is done with open
 291          *   if there is a writer (or reader) waiting for us, wake them up
 292          *      and indicate that at least 1 read (or write) open has occurred
 293          *      this is need in the event the read (or write) side closes
 294          *      before the writer (or reader) has a chance to wake up
 295          *      i.e. it sees that a reader (or writer) was once there
 296          */
 297         if (flag & FREAD) {
 298                 fnp->fn_rsynccnt--;  /* reader done with open */
 299                 if (fnp->fn_flag & FIFOSYNC) {
 300                         /*
 301                          * This indicates that a read open has occurred
 302                          * Only need to set if writer is actually asleep
 303                          * Flag will be consumed by writer.
 304                          */
 305                         fnp->fn_flag |= FIFOROCR;
 306                         cv_broadcast(&fnp->fn_wait_cv);
 307                 }
 308         }
 309         if (flag & FWRITE) {
 310                 fnp->fn_wsynccnt--;  /* writer done with open */
 311                 if (fnp->fn_flag & FIFOSYNC) {
 312                         /*
 313                          * This indicates that a write open has occurred
 314                          * Only need to set if reader is actually asleep
 315                          * Flag will be consumed by reader.
 316                          */
 317                         fnp->fn_flag |= FIFOWOCR;
 318                         cv_broadcast(&fnp->fn_wait_cv);
 319                 }
 320         }
 321 
 322         fnp->fn_flag &= ~FIFOSYNC;
 323 
 324         /*
 325          * errors don't wait around.. just return
 326          * Note: XXX other end will wake up and continue despite error.
 327          * There is no defined semantic on the correct course of option
 328          * so we do what we've done in the past
 329          */
 330         if (error != 0) {
 331                 mutex_exit(&fnp->fn_lock->flk_lock);
 332                 goto done;
 333         }
 334         ASSERT(fnp->fn_rsynccnt <= fnp->fn_rcnt);
 335         ASSERT(fnp->fn_wsynccnt <= fnp->fn_wcnt);
 336         /*
 337          * FIFOWOCR (or FIFOROCR) indicates that the writer (or reader)
 338          * has woken us up and is done with open (this way, if the other
 339          * end has made it to close, we don't block forever in open)
 340          * fn_wnct == fn_wsynccnt (or fn_rcnt == fn_rsynccnt) indicates
 341          * that no writer (or reader) has yet made it through open
 342          * This has the side benefit of that the first
 343          * reader (or writer) will wait until the other end finishes open
 344          */
 345         if (flag & FREAD) {
 346                 while ((fnp->fn_flag & FIFOWOCR) == 0 &&
 347                     fnp->fn_wcnt == fnp->fn_wsynccnt) {
 348                         if (flag & (FNDELAY|FNONBLOCK)) {
 349                                 mutex_exit(&fnp->fn_lock->flk_lock);
 350                                 goto done;
 351                         }
 352                         fnp->fn_insync++;
 353                         fnp->fn_flag |= FIFOSYNC;
 354                         if (!cv_wait_sig_swap(&fnp->fn_wait_cv,
 355                             &fnp->fn_lock->flk_lock)) {
 356                                 /*
 357                                  * Last reader to wakeup clear writer
 358                                  * Clear both writer and reader open
 359                                  * occurred flag incase other end is O_RDWR
 360                                  */
 361                                 if (--fnp->fn_insync == 0 &&
 362                                     fnp->fn_flag & FIFOWOCR) {
 363                                         fnp->fn_flag &= ~(FIFOWOCR|FIFOROCR);
 364                                 }
 365                                 mutex_exit(&fnp->fn_lock->flk_lock);
 366                                 (void) fifo_close(*vpp, flag, 1, 0, crp, ct);
 367                                 error = EINTR;
 368                                 goto done;
 369                         }
 370                         /*
 371                          * Last reader to wakeup clear writer open occurred flag
 372                          * Clear both writer and reader open occurred flag
 373                          * incase other end is O_RDWR
 374                          */
 375                         if (--fnp->fn_insync == 0 &&
 376                             fnp->fn_flag & FIFOWOCR) {
 377                                 fnp->fn_flag &= ~(FIFOWOCR|FIFOROCR);
 378                                 break;
 379                         }
 380                 }
 381         } else if (flag & FWRITE) {
 382                 while ((fnp->fn_flag & FIFOROCR) == 0 &&
 383                     fnp->fn_rcnt == fnp->fn_rsynccnt) {
 384                         if ((flag & (FNDELAY|FNONBLOCK)) && fnp->fn_rcnt == 0) {
 385                                 mutex_exit(&fnp->fn_lock->flk_lock);
 386                                 (void) fifo_close(*vpp, flag, 1, 0, crp, ct);
 387                                 error = ENXIO;
 388                                 goto done;
 389                         }
 390                         fnp->fn_flag |= FIFOSYNC;
 391                         fnp->fn_insync++;
 392                         if (!cv_wait_sig_swap(&fnp->fn_wait_cv,
 393                             &fnp->fn_lock->flk_lock)) {
 394                                 /*
 395                                  * Last writer to wakeup clear
 396                                  * Clear both writer and reader open
 397                                  * occurred flag in case other end is O_RDWR
 398                                  */
 399                                 if (--fnp->fn_insync == 0 &&
 400                                     (fnp->fn_flag & FIFOROCR) != 0) {
 401                                         fnp->fn_flag &= ~(FIFOWOCR|FIFOROCR);
 402                                 }
 403                                 mutex_exit(&fnp->fn_lock->flk_lock);
 404                                 (void) fifo_close(*vpp, flag, 1, 0, crp, ct);
 405                                 error = EINTR;
 406                                 goto done;
 407                         }
 408                         /*
 409                          * Last writer to wakeup clear reader open occurred flag
 410                          * Clear both writer and reader open
 411                          * occurred flag in case other end is O_RDWR
 412                          */
 413                         if (--fnp->fn_insync == 0 &&
 414                             (fnp->fn_flag & FIFOROCR) != 0) {
 415                                 fnp->fn_flag &= ~(FIFOWOCR|FIFOROCR);
 416                                 break;
 417                         }
 418                 }
 419         }
 420         mutex_exit(&fn_lock->flk_lock);
 421 done:
 422         return (error);
 423 }
 424 
 425 /*
 426  * Close down a stream.
 427  * Call cleanlocks() and strclean() on every close.
 428  * For last close send hangup message and force
 429  * the other end of a named pipe to be unmounted.
 430  * Mount guarantees that the mounted end will only call fifo_close()
 431  * with a count of 1 when the unmount occurs.
 432  * This routine will close down one end of a pipe or FIFO
 433  * and free the stream head via strclose()
 434  */
 435 /*ARGSUSED*/
 436 int
 437 fifo_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *crp,
 438         caller_context_t *ct)
 439 {
 440         fifonode_t      *fnp            = VTOF(vp);
 441         fifonode_t      *fn_dest        = fnp->fn_dest;
 442         int             error           = 0;
 443         fifolock_t      *fn_lock        = fnp->fn_lock;
 444         queue_t         *sd_wrq;
 445         vnode_t         *fn_dest_vp;
 446         int             senthang = 0;
 447 
 448         ASSERT(vp->v_stream != NULL);
 449         /*
 450          * clean locks and clear events.
 451          */
 452         (void) cleanlocks(vp, ttoproc(curthread)->p_pid, 0);
 453         cleanshares(vp, ttoproc(curthread)->p_pid);
 454         strclean(vp);
 455 
 456         /*
 457          * If a file still has the pipe/FIFO open, return.
 458          */
 459         if (count > 1)
 460                 return (0);
 461 
 462 
 463         sd_wrq = strvp2wq(vp);
 464         mutex_enter(&fn_lock->flk_lock);
 465 
 466         /*
 467          * wait for pending opens to finish up
 468          * note: this also has the side effect of single threading closes
 469          */
 470         while (fn_lock->flk_ocsync)
 471                 cv_wait(&fn_lock->flk_wait_cv, &fn_lock->flk_lock);
 472 
 473         fn_lock->flk_ocsync = 1;
 474 
 475         if (flag & FREAD) {
 476                 fnp->fn_rcnt--;
 477         }
 478         /*
 479          * If we are last writer wake up sleeping readers
 480          * (They'll figure out that there are no more writers
 481          * and do the right thing)
 482          * send hangup down stream so that stream head will do the
 483          * right thing.
 484          */
 485         if (flag & FWRITE) {
 486                 if (--fnp->fn_wcnt == 0 && fn_dest->fn_rcnt > 0) {
 487                         if ((fn_dest->fn_flag & (FIFOFAST | FIFOWANTR)) ==
 488                             (FIFOFAST | FIFOWANTR)) {
 489                                 /*
 490                                  * While we're at it, clear FIFOWANTW too
 491                                  * Wake up any sleeping readers or
 492                                  * writers.
 493                                  */
 494                                 fn_dest->fn_flag &= ~(FIFOWANTR | FIFOWANTW);
 495                                 cv_broadcast(&fn_dest->fn_wait_cv);
 496                         }
 497                         /*
 498                          * This is needed incase the other side
 499                          * was opened non-blocking.  It is the
 500                          * only way we can tell that wcnt is 0 because
 501                          * of close instead of never having a writer
 502                          */
 503                         if (!(fnp->fn_flag & ISPIPE))
 504                                 fnp->fn_flag |= FIFOCLOSE;
 505                         /*
 506                          * Note: sending hangup effectively shuts down
 507                          * both reader and writer at other end.
 508                          */
 509                         (void) putnextctl_wait(sd_wrq, M_HANGUP);
 510                         senthang = 1;
 511                 }
 512         }
 513 
 514         /*
 515          * For FIFOs we need to indicate to stream head that last reader
 516          * has gone away so that an error is generated
 517          * Pipes just need to wake up the other end so that it can
 518          * notice this end has gone away.
 519          */
 520 
 521         if (fnp->fn_rcnt == 0 && fn_dest->fn_wcnt > 0) {
 522                 if ((fn_dest->fn_flag & (FIFOFAST | FIFOWANTW)) ==
 523                     (FIFOFAST | FIFOWANTW)) {
 524                         /*
 525                          * wake up any sleeping writers
 526                          */
 527                         fn_dest->fn_flag &= ~FIFOWANTW;
 528                         cv_broadcast(&fn_dest->fn_wait_cv);
 529                 }
 530         }
 531 
 532         /*
 533          * if there are still processes with this FIFO open
 534          *      clear open/close sync flag
 535          *      and just return;
 536          */
 537         if (--fnp->fn_open > 0) {
 538                 ASSERT((fnp->fn_rcnt + fnp->fn_wcnt) != 0);
 539                 fn_lock->flk_ocsync = 0;
 540                 cv_broadcast(&fn_lock->flk_wait_cv);
 541                 mutex_exit(&fn_lock->flk_lock);
 542                 return (0);
 543         }
 544 
 545         /*
 546          * Need to send HANGUP if other side is still open
 547          * (fnp->fn_rcnt or fnp->fn_wcnt may not be zero (some thread
 548          * on this end of the pipe may still be in fifo_open())
 549          *
 550          * Note: we can get here with fn_rcnt and fn_wcnt != 0 if some
 551          * thread is blocked somewhere in the fifo_open() path prior to
 552          * fifo_stropen() incrementing fn_open.  This can occur for
 553          * normal FIFOs as well as named pipes.  fn_rcnt and
 554          * fn_wcnt only indicate attempts to open. fn_open indicates
 555          * successful opens. Partially opened FIFOs should proceed
 556          * normally; i.e. they will appear to be new opens.  Partially
 557          * opened pipes will probably fail.
 558          */
 559 
 560         if (fn_dest->fn_open && senthang == 0)
 561                 (void) putnextctl_wait(sd_wrq, M_HANGUP);
 562 
 563 
 564         /*
 565          * If this a pipe and this is the first end to close,
 566          * then we have a bit of cleanup work to do.
 567          *      Mark both ends of pipe as closed.
 568          *      Wake up anybody blocked at the other end and for named pipes,
 569          *      Close down this end of the stream
 570          *      Allow other opens/closes to continue
 571          *      force an unmount of other end.
 572          * Otherwise if this is last close,
 573          *      flush messages,
 574          *      close down the stream
 575          *      allow other opens/closes to continue
 576          */
 577         fnp->fn_flag &= ~FIFOISOPEN;
 578         if ((fnp->fn_flag & ISPIPE) && !(fnp->fn_flag & FIFOCLOSE)) {
 579                 fnp->fn_flag |= FIFOCLOSE;
 580                 fn_dest->fn_flag |= FIFOCLOSE;
 581                 if (fnp->fn_flag & FIFOFAST)
 582                         fifo_fastflush(fnp);
 583                 if (vp->v_stream != NULL) {
 584                         mutex_exit(&fn_lock->flk_lock);
 585                         (void) strclose(vp, flag, crp);
 586                         mutex_enter(&fn_lock->flk_lock);
 587                 }
 588                 cv_broadcast(&fn_dest->fn_wait_cv);
 589                 /*
 590                  * allow opens and closes to proceed
 591                  * Since this end is now closed down, any attempt
 592                  * to do anything with this end will fail
 593                  */
 594                 fn_lock->flk_ocsync = 0;
 595                 cv_broadcast(&fn_lock->flk_wait_cv);
 596                 fn_dest_vp = FTOV(fn_dest);
 597                 /*
 598                  * if other end of pipe has been opened and it's
 599                  * a named pipe, unmount it
 600                  */
 601                 if (fn_dest_vp->v_stream &&
 602                     (fn_dest_vp->v_stream->sd_flag & STRMOUNT)) {
 603                         /*
 604                          * We must hold the destination vnode because
 605                          * nm_unmountall() causes close to be called
 606                          * for the other end of named pipe.  This
 607                          * could free the vnode before we are ready.
 608                          */
 609                         VN_HOLD(fn_dest_vp);
 610                         mutex_exit(&fn_lock->flk_lock);
 611                         error = nm_unmountall(fn_dest_vp, crp);
 612                         ASSERT(error == 0);
 613                         VN_RELE(fn_dest_vp);
 614                 } else {
 615                         ASSERT(vp->v_count >= 1);
 616                         mutex_exit(&fn_lock->flk_lock);
 617                 }
 618         } else {
 619                 if (fnp->fn_flag & FIFOFAST)
 620                         fifo_fastflush(fnp);
 621 #if DEBUG
 622                 fn_dest_vp = FTOV(fn_dest);
 623                 if (fn_dest_vp->v_stream)
 624                         ASSERT((fn_dest_vp->v_stream->sd_flag & STRMOUNT) == 0);
 625 #endif
 626                 if (vp->v_stream != NULL) {
 627                         mutex_exit(&fn_lock->flk_lock);
 628                         (void) strclose(vp, flag, crp);
 629                         mutex_enter(&fn_lock->flk_lock);
 630                 }
 631                 fn_lock->flk_ocsync = 0;
 632                 cv_broadcast(&fn_lock->flk_wait_cv);
 633                 cv_broadcast(&fn_dest->fn_wait_cv);
 634                 mutex_exit(&fn_lock->flk_lock);
 635         }
 636         return (error);
 637 }
 638 
 639 /*
 640  * Read from a pipe or FIFO.
 641  * return 0 if....
 642  *    (1) user read request is 0 or no stream
 643  *    (2) broken pipe with no data
 644  *    (3) write-only FIFO with no data
 645  *    (4) no data and FNDELAY flag is set.
 646  * Otherwise return
 647  *      EAGAIN if FNONBLOCK is set and no data to read
 648  *      EINTR if signal received while waiting for data
 649  *
 650  * While there is no data to read....
 651  *   -  if the NDELAY/NONBLOCK flag is set, return 0/EAGAIN.
 652  *   -  wait for a write.
 653  *
 654  */
 655 /*ARGSUSED*/
 656 
 657 static int
 658 fifo_read(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *crp,
 659         caller_context_t *ct)
 660 {
 661         fifonode_t      *fnp            = VTOF(vp);
 662         fifonode_t      *fn_dest;
 663         fifolock_t      *fn_lock        = fnp->fn_lock;
 664         int             error           = 0;
 665         mblk_t          *bp;
 666 
 667         ASSERT(vp->v_stream != NULL);
 668         if (uiop->uio_resid == 0)
 669                 return (0);
 670 
 671         mutex_enter(&fn_lock->flk_lock);
 672 
 673         TRACE_2(TR_FAC_FIFO, TR_FIFOREAD_IN, "fifo_read in:%p fnp %p", vp, fnp);
 674 
 675         if (! (fnp->fn_flag & FIFOFAST))
 676                 goto stream_mode;
 677 
 678         fn_dest = fnp->fn_dest;
 679         /*
 680          * Check for data on our input queue
 681          */
 682 
 683         while (fnp->fn_count == 0) {
 684                 /*
 685                  * No data on first attempt and no writer, then EOF
 686                  */
 687                 if (fn_dest->fn_wcnt == 0 || fn_dest->fn_rcnt == 0) {
 688                         mutex_exit(&fn_lock->flk_lock);
 689                         return (0);
 690                 }
 691                 /*
 692                  * no data found.. if non-blocking, return EAGAIN
 693                  * otherwise 0.
 694                  */
 695                 if (uiop->uio_fmode & (FNDELAY|FNONBLOCK)) {
 696                         mutex_exit(&fn_lock->flk_lock);
 697                         if (uiop->uio_fmode & FNONBLOCK)
 698                                 return (EAGAIN);
 699                         return (0);
 700                 }
 701 
 702                 /*
 703                  * Note: FIFOs can get here with FIFOCLOSE set if
 704                  * write side is in the middle of opeining after
 705                  * it once closed. Pipes better not have FIFOCLOSE set
 706                  */
 707                 ASSERT((fnp->fn_flag & (ISPIPE|FIFOCLOSE)) !=
 708                     (ISPIPE|FIFOCLOSE));
 709                 /*
 710                  * wait for data
 711                  */
 712                 fnp->fn_flag |= FIFOWANTR;
 713 
 714                 TRACE_1(TR_FAC_FIFO, TR_FIFOREAD_WAIT, "fiforead wait: %p", vp);
 715 
 716                 if (!cv_wait_sig_swap(&fnp->fn_wait_cv,
 717                     &fn_lock->flk_lock)) {
 718                         error = EINTR;
 719                         goto done;
 720                 }
 721 
 722                 TRACE_1(TR_FAC_FIFO, TR_FIFOREAD_WAKE,
 723                     "fiforead awake: %p", vp);
 724 
 725                 /*
 726                  * check to make sure we are still in fast mode
 727                  */
 728                 if (!(fnp->fn_flag & FIFOFAST))
 729                         goto stream_mode;
 730         }
 731 
 732         ASSERT(fnp->fn_mp != NULL);
 733 
 734         /* For pipes copy should not bypass cache */
 735         uiop->uio_extflg |= UIO_COPY_CACHED;
 736 
 737         do {
 738                 int bpsize = MBLKL(fnp->fn_mp);
 739                 int uiosize = MIN(bpsize, uiop->uio_resid);
 740 
 741                 error = uiomove(fnp->fn_mp->b_rptr, uiosize, UIO_READ, uiop);
 742                 if (error != 0)
 743                         break;
 744 
 745                 fnp->fn_count -= uiosize;
 746 
 747                 if (bpsize <= uiosize) {
 748                         bp = fnp->fn_mp;
 749                         fnp->fn_mp = fnp->fn_mp->b_cont;
 750                         freeb(bp);
 751 
 752                         if (uiop->uio_resid == 0)
 753                                 break;
 754 
 755                         while (fnp->fn_mp == NULL && fn_dest->fn_wwaitcnt > 0) {
 756                                 ASSERT(fnp->fn_count == 0);
 757 
 758                                 if (uiop->uio_fmode & (FNDELAY|FNONBLOCK))
 759                                         goto trywake;
 760 
 761                                 /*
 762                                  * We've consumed all available data but there
 763                                  * are threads waiting to write more, let them
 764                                  * proceed before bailing.
 765                                  */
 766 
 767                                 fnp->fn_flag |= FIFOWANTR;
 768                                 fifo_wakewriter(fn_dest, fn_lock);
 769 
 770                                 if (!cv_wait_sig(&fnp->fn_wait_cv,
 771                                     &fn_lock->flk_lock))
 772                                         goto trywake;
 773 
 774                                 if (!(fnp->fn_flag & FIFOFAST))
 775                                         goto stream_mode;
 776                         }
 777                 } else {
 778                         fnp->fn_mp->b_rptr += uiosize;
 779                         ASSERT(uiop->uio_resid == 0);
 780                 }
 781         } while (uiop->uio_resid != 0 && fnp->fn_mp != NULL);
 782 
 783 trywake:
 784         ASSERT(msgdsize(fnp->fn_mp) == fnp->fn_count);
 785 
 786         /*
 787          * wake up any blocked writers, processes
 788          * sleeping on POLLWRNORM, or processes waiting for SIGPOLL
 789          * Note: checking for fn_count < Fifohiwat emulates
 790          * STREAMS functionality when low water mark is 0
 791          */
 792         if (fn_dest->fn_flag & (FIFOWANTW | FIFOHIWATW) &&
 793             fnp->fn_count < Fifohiwat) {
 794                 fifo_wakewriter(fn_dest, fn_lock);
 795         }
 796         goto done;
 797 
 798         /*
 799          * FIFO is in streams mode.. let the stream head handle it
 800          */
 801 stream_mode:
 802 
 803         mutex_exit(&fn_lock->flk_lock);
 804         TRACE_1(TR_FAC_FIFO,
 805             TR_FIFOREAD_STREAM, "fifo_read stream_mode:%p", vp);
 806 
 807         error = strread(vp, uiop, crp);
 808 
 809         mutex_enter(&fn_lock->flk_lock);
 810 
 811 done:
 812         /*
 813          * vnode update access time
 814          */
 815         if (error == 0) {
 816                 time_t now = gethrestime_sec();
 817 
 818                 if (fnp->fn_flag & ISPIPE)
 819                         fnp->fn_dest->fn_atime = now;
 820                 fnp->fn_atime = now;
 821         }
 822         TRACE_2(TR_FAC_FIFO, TR_FIFOREAD_OUT,
 823             "fifo_read out:%p error %d", vp, error);
 824         mutex_exit(&fn_lock->flk_lock);
 825         return (error);
 826 }
 827 
 828 /*
 829  * send SIGPIPE and return EPIPE if ...
 830  *   (1) broken pipe (essentially, reader is gone)
 831  *   (2) FIFO is not open for reading
 832  * return 0 if...
 833  *   (1) no stream
 834  *   (2) user write request is for 0 bytes and SW_SNDZERO is not set
 835  *      Note: SW_SNDZERO can't be set in fast mode
 836  * While the stream is flow controlled....
 837  *   -  if the NDELAY/NONBLOCK flag is set, return 0/EAGAIN.
 838  *   -  unlock the fifonode and sleep waiting for a reader.
 839  *   -  if a pipe and it has a mate, sleep waiting for its mate
 840  *      to read.
 841  */
 842 /*ARGSUSED*/
 843 static int
 844 fifo_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *crp,
 845         caller_context_t *ct)
 846 {
 847         struct fifonode *fnp, *fn_dest;
 848         fifolock_t      *fn_lock;
 849         struct stdata   *stp;
 850         int             error   = 0;
 851         int             write_size;
 852         int             size;
 853         int             fmode;
 854         mblk_t          *bp;
 855         boolean_t       hotread;
 856 
 857         ASSERT(vp->v_stream);
 858         uiop->uio_loffset = 0;
 859         stp     = vp->v_stream;
 860 
 861         /*
 862          * remember original number of bytes requested. Used to determine if
 863          * we actually have written anything at all
 864          */
 865         write_size = uiop->uio_resid;
 866 
 867         /*
 868          * only send zero-length messages if SW_SNDZERO is set
 869          * Note: we will be in streams mode if SW_SNDZERO is set
 870          * XXX this streams interface should not be exposed
 871          */
 872         if ((write_size == 0) && !(stp->sd_wput_opt & SW_SNDZERO))
 873                 return (0);
 874 
 875         fnp = VTOF(vp);
 876         fn_lock = fnp->fn_lock;
 877         fn_dest = fnp->fn_dest;
 878 
 879         mutex_enter(&fn_lock->flk_lock);
 880 
 881         TRACE_3(TR_FAC_FIFO, TR_FIFOWRITE_IN,
 882             "fifo_write in:%p fnp %p size %d", vp, fnp, write_size);
 883 
 884         /*
 885          * oops, no readers, error
 886          */
 887         if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
 888                 goto epipe;
 889         }
 890 
 891         /*
 892          * if we are not in fast mode, let streams handle it
 893          */
 894         if (!(fnp->fn_flag & FIFOFAST))
 895                 goto stream_mode;
 896 
 897         fmode = uiop->uio_fmode & (FNDELAY|FNONBLOCK);
 898 
 899         /* For pipes copy should not bypass cache */
 900         uiop->uio_extflg |= UIO_COPY_CACHED;
 901 
 902         do  {
 903                 /*
 904                  * check to make sure we are not over high water mark
 905                  */
 906                 while (fn_dest->fn_count >= Fifohiwat) {
 907                         /*
 908                          * Indicate that we have gone over high
 909                          * water mark
 910                          */
 911                         /*
 912                          * if non-blocking, return
 913                          * only happens first time through loop
 914                          */
 915                         if (fmode) {
 916                                 fnp->fn_flag |= FIFOHIWATW;
 917                                 if (uiop->uio_resid == write_size) {
 918                                         mutex_exit(&fn_lock->flk_lock);
 919                                         if (fmode & FNDELAY)
 920                                                 return (0);
 921                                         else
 922                                                 return (EAGAIN);
 923                                 }
 924                                 goto done;
 925                         }
 926 
 927                         /*
 928                          * wait for things to drain
 929                          */
 930                         fnp->fn_flag |= FIFOWANTW;
 931                         fnp->fn_wwaitcnt++;
 932                         TRACE_1(TR_FAC_FIFO, TR_FIFOWRITE_WAIT,
 933                             "fifo_write wait: %p", vp);
 934                         if (!cv_wait_sig_swap(&fnp->fn_wait_cv,
 935                             &fn_lock->flk_lock)) {
 936                                 error = EINTR;
 937                                 fnp->fn_wwaitcnt--;
 938                                 fifo_wakereader(fn_dest, fn_lock);
 939                                 goto done;
 940                         }
 941                         fnp->fn_wwaitcnt--;
 942 
 943                         TRACE_1(TR_FAC_FIFO, TR_FIFOWRITE_WAKE,
 944                             "fifo_write wake: %p", vp);
 945 
 946                         /*
 947                          * check to make sure we're still in fast mode
 948                          */
 949                         if (!(fnp->fn_flag & FIFOFAST))
 950                                 goto stream_mode;
 951 
 952                         /*
 953                          * make sure readers didn't go away
 954                          */
 955                         if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
 956                                 goto epipe;
 957                         }
 958                 }
 959                 /*
 960                  * If the write will put us over the high water mark,
 961                  * then we must break the message up into PIPE_BUF
 962                  * chunks to stay compliant with STREAMS
 963                  */
 964                 if (uiop->uio_resid + fn_dest->fn_count > Fifohiwat)
 965                         size = MIN(uiop->uio_resid, PIPE_BUF);
 966                 else
 967                         size = uiop->uio_resid;
 968 
 969                 /*
 970                  * We don't need to hold flk_lock across the allocb() and
 971                  * uiomove().  However, on a multiprocessor machine where both
 972                  * the reader and writer thread are on cpu's, we must be
 973                  * careful to only drop the lock if there's data to be read.
 974                  * This forces threads entering fifo_read() to spin or block
 975                  * on flk_lock, rather than acquiring flk_lock only to
 976                  * discover there's no data to read and being forced to go
 977                  * back to sleep, only to be woken up microseconds later by
 978                  * this writer thread.
 979                  */
 980                 hotread = fn_dest->fn_count > 0;
 981                 if (hotread) {
 982                         if (!fifo_stayfast_enter(fnp))
 983                                 goto stream_mode;
 984                         mutex_exit(&fn_lock->flk_lock);
 985                 }
 986 
 987                 ASSERT(size != 0);
 988                 /*
 989                  * Align the mblk with the user data so that
 990                  * copying in the data can take advantage of
 991                  * the double word alignment
 992                  */
 993                 if ((bp = allocb(size + 8, BPRI_MED)) == NULL) {
 994                         if (!hotread)
 995                                 mutex_exit(&fn_lock->flk_lock);
 996 
 997                         error = strwaitbuf(size, BPRI_MED);
 998 
 999                         mutex_enter(&fn_lock->flk_lock);
1000 
1001                         if (hotread) {
1002                                 /*
1003                                  * As we dropped the mutex for a moment, we
1004                                  * need to wake up any thread waiting to be
1005                                  * allowed to go from fast mode to stream mode.
1006                                  */
1007                                 fifo_stayfast_exit(fnp);
1008                         }
1009                         if (error != 0) {
1010                                 goto done;
1011                         }
1012                         /*
1013                          * check to make sure we're still in fast mode
1014                          */
1015                         if (!(fnp->fn_flag & FIFOFAST))
1016                                 goto stream_mode;
1017 
1018                         /*
1019                          * make sure readers didn't go away
1020                          */
1021                         if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
1022                                 goto epipe;
1023                         }
1024                         /*
1025                          * some other thread could have gotten in
1026                          * need to go back and check hi water mark
1027                          */
1028                         continue;
1029                 }
1030                 bp->b_rptr += ((uintptr_t)uiop->uio_iov->iov_base & 0x7);
1031                 bp->b_wptr = bp->b_rptr + size;
1032                 error = uiomove((caddr_t)bp->b_rptr, size, UIO_WRITE, uiop);
1033                 if (hotread) {
1034                         mutex_enter(&fn_lock->flk_lock);
1035                         /*
1036                          * As we dropped the mutex for a moment, we need to:
1037                          * - wake up any thread waiting to be allowed to go
1038                          *   from fast mode to stream mode,
1039                          * - make sure readers didn't go away.
1040                          */
1041                         fifo_stayfast_exit(fnp);
1042                         if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
1043                                 freeb(bp);
1044                                 goto epipe;
1045                         }
1046                 }
1047 
1048                 if (error != 0) {
1049                         freeb(bp);
1050                         goto done;
1051                 }
1052 
1053                 fn_dest->fn_count += size;
1054                 if (fn_dest->fn_mp != NULL) {
1055                         fn_dest->fn_tail->b_cont = bp;
1056                         fn_dest->fn_tail = bp;
1057                 } else {
1058                         fn_dest->fn_mp = fn_dest->fn_tail = bp;
1059                         /*
1060                          * This is the first bit of data; wake up any sleeping
1061                          * readers, processes blocked in poll, and those
1062                          * expecting a SIGPOLL.
1063                          */
1064                         fifo_wakereader(fn_dest, fn_lock);
1065                 }
1066         } while (uiop->uio_resid != 0);
1067 
1068         goto done;
1069 
1070 stream_mode:
1071         /*
1072          * streams mode
1073          *  let the stream head handle the write
1074          */
1075         ASSERT(MUTEX_HELD(&fn_lock->flk_lock));
1076 
1077         mutex_exit(&fn_lock->flk_lock);
1078         TRACE_1(TR_FAC_FIFO,
1079             TR_FIFOWRITE_STREAM, "fifo_write stream_mode:%p", vp);
1080 
1081         error = strwrite(vp, uiop, crp);
1082 
1083         mutex_enter(&fn_lock->flk_lock);
1084 
1085 done:
1086         /*
1087          * update vnode modification and change times
1088          * make sure there were no errors and some data was transferred
1089          */
1090         if (error == 0 && write_size != uiop->uio_resid) {
1091                 time_t now = gethrestime_sec();
1092 
1093                 if (fnp->fn_flag & ISPIPE) {
1094                         fn_dest->fn_mtime = fn_dest->fn_ctime = now;
1095                 }
1096                 fnp->fn_mtime = fnp->fn_ctime = now;
1097         } else if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
1098                 goto epipe;
1099         }
1100         TRACE_3(TR_FAC_FIFO, TR_FIFOWRITE_OUT,
1101             "fifo_write out: vp %p error %d fnp %p", vp, error, fnp);
1102         mutex_exit(&fn_lock->flk_lock);
1103         return (error);
1104 epipe:
1105         error = EPIPE;
1106         TRACE_3(TR_FAC_FIFO, TR_FIFOWRITE_OUT,
1107             "fifo_write out: vp %p error %d fnp %p", vp, error, fnp);
1108         mutex_exit(&fn_lock->flk_lock);
1109         tsignal(curthread, SIGPIPE);
1110         return (error);
1111 }
1112 
1113 /*ARGSUSED6*/
1114 static int
1115 fifo_ioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1116         cred_t *cr, int *rvalp, caller_context_t *ct)
1117 {
1118         /*
1119          * Just a quick check
1120          * Once we go to streams mode we don't ever revert back
1121          * So we do this quick check so as not to incur the overhead
1122          * associated with acquiring the lock
1123          */
1124         return ((VTOF(vp)->fn_flag & FIFOFAST) ?
1125             fifo_fastioctl(vp, cmd, arg, mode, cr, rvalp) :
1126             fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1127 }
1128 
1129 static int
1130 fifo_fastioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1131         cred_t *cr, int *rvalp)
1132 {
1133         fifonode_t      *fnp            = VTOF(vp);
1134         fifonode_t      *fn_dest;
1135         int             error           = 0;
1136         fifolock_t      *fn_lock        = fnp->fn_lock;
1137         int             cnt;
1138 
1139         /*
1140          * tty operations not allowed
1141          */
1142         if (((cmd & IOCTYPE) == LDIOC) ||
1143             ((cmd & IOCTYPE) == tIOC) ||
1144             ((cmd & IOCTYPE) == TIOC)) {
1145                 return (EINVAL);
1146         }
1147 
1148         mutex_enter(&fn_lock->flk_lock);
1149 
1150         if (!(fnp->fn_flag & FIFOFAST)) {
1151                 goto stream_mode;
1152         }
1153 
1154         switch (cmd) {
1155 
1156         /*
1157          * Things we can't handle
1158          * These will switch us to streams mode.
1159          */
1160         default:
1161         case I_STR:
1162         case I_SRDOPT:
1163         case I_PUSH:
1164         case I_FDINSERT:
1165         case I_SENDFD:
1166         case I_RECVFD:
1167         case I_E_RECVFD:
1168         case I_ATMARK:
1169         case I_CKBAND:
1170         case I_GETBAND:
1171         case I_SWROPT:
1172                 goto turn_fastoff;
1173 
1174         /*
1175          * Things that don't do damage
1176          * These things don't adjust the state of the
1177          * stream head (i_setcltime does, but we don't care)
1178          */
1179         case I_FIND:
1180         case I_GETSIG:
1181         case FIONBIO:
1182         case FIOASYNC:
1183         case I_GRDOPT:  /* probably should not get this, but no harm */
1184         case I_GWROPT:
1185         case I_LIST:
1186         case I_SETCLTIME:
1187         case I_GETCLTIME:
1188                 mutex_exit(&fn_lock->flk_lock);
1189                 return (strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp));
1190 
1191         case I_CANPUT:
1192                 /*
1193                  * We can only handle normal band canputs.
1194                  * XXX : We could just always go to stream mode; after all
1195                  * canput is a streams semantics type thing
1196                  */
1197                 if (arg != 0) {
1198                         goto turn_fastoff;
1199                 }
1200                 *rvalp = (fnp->fn_dest->fn_count < Fifohiwat) ? 1 : 0;
1201                 mutex_exit(&fn_lock->flk_lock);
1202                 return (0);
1203 
1204         case I_NREAD:
1205                 /*
1206                  * This may seem a bit silly for non-streams semantics,
1207                  * (After all, if they really want a message, they'll
1208                  * probably use getmsg() anyway). but it doesn't hurt
1209                  */
1210                 error = copyout((caddr_t)&fnp->fn_count, (caddr_t)arg,
1211                     sizeof (cnt));
1212                 if (error == 0) {
1213                         *rvalp = (fnp->fn_count == 0) ? 0 : 1;
1214                 }
1215                 break;
1216 
1217         case FIORDCHK:
1218                 *rvalp = fnp->fn_count;
1219                 break;
1220 
1221         case I_PEEK:
1222         {
1223                 STRUCT_DECL(strpeek, strpeek);
1224                 struct uio      uio;
1225                 struct iovec    iov;
1226                 int             count;
1227                 mblk_t          *bp;
1228                 int             len;
1229 
1230                 STRUCT_INIT(strpeek, mode);
1231 
1232                 if (fnp->fn_count == 0) {
1233                         *rvalp = 0;
1234                         break;
1235                 }
1236 
1237                 error = copyin((caddr_t)arg, STRUCT_BUF(strpeek),
1238                     STRUCT_SIZE(strpeek));
1239                 if (error)
1240                         break;
1241 
1242                 /*
1243                  * can't have any high priority message when in fast mode
1244                  */
1245                 if (STRUCT_FGET(strpeek, flags) & RS_HIPRI) {
1246                         *rvalp = 0;
1247                         break;
1248                 }
1249 
1250                 len = STRUCT_FGET(strpeek, databuf.maxlen);
1251                 if (len <= 0) {
1252                         STRUCT_FSET(strpeek, databuf.len, len);
1253                 } else {
1254                         iov.iov_base = STRUCT_FGETP(strpeek, databuf.buf);
1255                         iov.iov_len = len;
1256                         uio.uio_iov = &iov;
1257                         uio.uio_iovcnt = 1;
1258                         uio.uio_loffset = 0;
1259                         uio.uio_segflg = UIO_USERSPACE;
1260                         uio.uio_fmode = 0;
1261                         /* For pipes copy should not bypass cache */
1262                         uio.uio_extflg = UIO_COPY_CACHED;
1263                         uio.uio_resid = iov.iov_len;
1264                         count = fnp->fn_count;
1265                         bp = fnp->fn_mp;
1266                         while (count > 0 && uio.uio_resid) {
1267                                 cnt = MIN(uio.uio_resid, MBLKL(bp));
1268                                 if ((error = uiomove((char *)bp->b_rptr, cnt,
1269                                     UIO_READ, &uio)) != 0) {
1270                                         break;
1271                                 }
1272                                 count -= cnt;
1273                                 bp = bp->b_cont;
1274                         }
1275                         STRUCT_FSET(strpeek, databuf.len, len - uio.uio_resid);
1276                 }
1277                 STRUCT_FSET(strpeek, flags, 0);
1278                 STRUCT_FSET(strpeek, ctlbuf.len, -1);
1279 
1280                 error = copyout(STRUCT_BUF(strpeek), (caddr_t)arg,
1281                     STRUCT_SIZE(strpeek));
1282                 if (error == 0 && len >= 0)
1283                         *rvalp = 1;
1284                 break;
1285         }
1286 
1287         case FIONREAD:
1288                 /*
1289                  * let user know total number of bytes in message queue
1290                  */
1291                 error = copyout((caddr_t)&fnp->fn_count, (caddr_t)arg,
1292                     sizeof (fnp->fn_count));
1293                 if (error == 0)
1294                         *rvalp = 0;
1295                 break;
1296 
1297         case I_SETSIG:
1298                 /*
1299                  * let streams set up the signal masking for us
1300                  * we just check to see if it's set
1301                  * XXX : this interface should not be visible
1302                  *  i.e. STREAM's framework is exposed.
1303                  */
1304                 error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
1305                 if (vp->v_stream->sd_sigflags & (S_INPUT|S_RDNORM|S_WRNORM))
1306                         fnp->fn_flag |= FIFOSETSIG;
1307                 else
1308                         fnp->fn_flag &= ~FIFOSETSIG;
1309                 break;
1310 
1311         case I_FLUSH:
1312                 /*
1313                  * flush them message queues
1314                  */
1315                 if (arg & ~FLUSHRW) {
1316                         error = EINVAL;
1317                         break;
1318                 }
1319                 if (arg & FLUSHR) {
1320                         fifo_fastflush(fnp);
1321                 }
1322                 fn_dest = fnp->fn_dest;
1323                 if ((arg & FLUSHW)) {
1324                         fifo_fastflush(fn_dest);
1325                 }
1326                 /*
1327                  * wake up any sleeping readers or writers
1328                  * (waking readers probably doesn't make sense, but it
1329                  *  doesn't hurt; i.e. we just got rid of all the data
1330                  *  what's to read ?)
1331                  */
1332                 if (fn_dest->fn_flag & (FIFOWANTW | FIFOWANTR)) {
1333                         fn_dest->fn_flag &= ~(FIFOWANTW | FIFOWANTR);
1334                         cv_broadcast(&fn_dest->fn_wait_cv);
1335                 }
1336                 *rvalp = 0;
1337                 break;
1338 
1339         /*
1340          * Since no band data can ever get on a fifo in fast mode
1341          * just return 0.
1342          */
1343         case I_FLUSHBAND:
1344                 error = 0;
1345                 *rvalp = 0;
1346                 break;
1347 
1348         /*
1349          * invalid calls for stream head or fifos
1350          */
1351 
1352         case I_POP:             /* shouldn't happen */
1353         case I_LOOK:
1354         case I_LINK:
1355         case I_PLINK:
1356         case I_UNLINK:
1357         case I_PUNLINK:
1358 
1359         /*
1360          * more invalid tty type of ioctls
1361          */
1362 
1363         case SRIOCSREDIR:
1364         case SRIOCISREDIR:
1365                 error = EINVAL;
1366                 break;
1367 
1368         }
1369         mutex_exit(&fn_lock->flk_lock);
1370         return (error);
1371 
1372 turn_fastoff:
1373         fifo_fastoff(fnp);
1374 
1375 stream_mode:
1376         /*
1377          * streams mode
1378          */
1379         mutex_exit(&fn_lock->flk_lock);
1380         return (fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1381 
1382 }
1383 
1384 /*
1385  * FIFO is in STREAMS mode; STREAMS framework does most of the work.
1386  */
1387 static int
1388 fifo_strioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1389         cred_t *cr, int *rvalp)
1390 {
1391         fifonode_t      *fnp = VTOF(vp);
1392         int             error;
1393         fifolock_t      *fn_lock;
1394 
1395         if (cmd == _I_GETPEERCRED) {
1396                 if (mode == FKIOCTL && fnp->fn_pcredp != NULL) {
1397                         k_peercred_t *kp = (k_peercred_t *)arg;
1398                         crhold(fnp->fn_pcredp);
1399                         kp->pc_cr = fnp->fn_pcredp;
1400                         kp->pc_cpid = fnp->fn_cpid;
1401                         return (0);
1402                 } else {
1403                         return (ENOTSUP);
1404                 }
1405         }
1406 
1407         error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
1408 
1409         switch (cmd) {
1410         /*
1411          * The FIFOSEND flag is set to inform other processes that a file
1412          * descriptor is pending at the stream head of this pipe.
1413          * The flag is cleared and the sending process is awoken when
1414          * this process has completed receiving the file descriptor.
1415          * XXX This could become out of sync if the process does I_SENDFDs
1416          * and opens on connld attached to the same pipe.
1417          */
1418         case I_RECVFD:
1419         case I_E_RECVFD:
1420                 if (error == 0) {
1421                         fn_lock = fnp->fn_lock;
1422                         mutex_enter(&fn_lock->flk_lock);
1423                         if (fnp->fn_flag & FIFOSEND) {
1424                                 fnp->fn_flag &= ~FIFOSEND;
1425                                 cv_broadcast(&fnp->fn_dest->fn_wait_cv);
1426                         }
1427                         mutex_exit(&fn_lock->flk_lock);
1428                 }
1429                 break;
1430         default:
1431                 break;
1432         }
1433 
1434         return (error);
1435 }
1436 
1437 /*
1438  * If shadowing a vnode (FIFOs), apply the VOP_GETATTR to the shadowed
1439  * vnode to Obtain the node information. If not shadowing (pipes), obtain
1440  * the node information from the credentials structure.
1441  */
1442 int
1443 fifo_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *crp,
1444         caller_context_t *ct)
1445 {
1446         int             error           = 0;
1447         fifonode_t      *fnp            = VTOF(vp);
1448         queue_t         *qp;
1449         qband_t         *bandp;
1450         fifolock_t      *fn_lock        = fnp->fn_lock;
1451 
1452         if (fnp->fn_realvp) {
1453                 /*
1454                  * for FIFOs or mounted pipes
1455                  */
1456                 if (error = VOP_GETATTR(fnp->fn_realvp, vap, flags, crp, ct))
1457                         return (error);
1458                 mutex_enter(&fn_lock->flk_lock);
1459                 /* set current times from fnode, even if older than vnode */
1460                 vap->va_atime.tv_sec = fnp->fn_atime;
1461                 vap->va_atime.tv_nsec = 0;
1462                 vap->va_mtime.tv_sec = fnp->fn_mtime;
1463                 vap->va_mtime.tv_nsec = 0;
1464                 vap->va_ctime.tv_sec = fnp->fn_ctime;
1465                 vap->va_ctime.tv_nsec = 0;
1466         } else {
1467                 /*
1468                  * for non-attached/ordinary pipes
1469                  */
1470                 vap->va_mode = 0;
1471                 mutex_enter(&fn_lock->flk_lock);
1472                 vap->va_atime.tv_sec = fnp->fn_atime;
1473                 vap->va_atime.tv_nsec = 0;
1474                 vap->va_mtime.tv_sec = fnp->fn_mtime;
1475                 vap->va_mtime.tv_nsec = 0;
1476                 vap->va_ctime.tv_sec = fnp->fn_ctime;
1477                 vap->va_ctime.tv_nsec = 0;
1478                 vap->va_uid = crgetuid(crp);
1479                 vap->va_gid = crgetgid(crp);
1480                 vap->va_nlink = 0;
1481                 vap->va_fsid = fifodev;
1482                 vap->va_nodeid = (ino64_t)fnp->fn_ino;
1483                 vap->va_rdev = 0;
1484         }
1485         vap->va_type = VFIFO;
1486         vap->va_blksize = PIPE_BUF;
1487         /*
1488          * Size is number of un-read bytes at the stream head and
1489          * nblocks is the unread bytes expressed in blocks.
1490          */
1491         if (vp->v_stream && (fnp->fn_flag & FIFOISOPEN)) {
1492                 if ((fnp->fn_flag & FIFOFAST)) {
1493                         vap->va_size = (u_offset_t)fnp->fn_count;
1494                 } else {
1495                         qp = RD((strvp2wq(vp)));
1496                         vap->va_size = (u_offset_t)qp->q_count;
1497                         if (qp->q_nband != 0) {
1498                                 mutex_enter(QLOCK(qp));
1499                                 for (bandp = qp->q_bandp; bandp;
1500                                     bandp = bandp->qb_next)
1501                                         vap->va_size += bandp->qb_count;
1502                                 mutex_exit(QLOCK(qp));
1503                         }
1504                 }
1505                 vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size);
1506         } else {
1507                 vap->va_size = (u_offset_t)0;
1508                 vap->va_nblocks = (fsblkcnt64_t)0;
1509         }
1510         mutex_exit(&fn_lock->flk_lock);
1511         vap->va_seq = 0;
1512         return (0);
1513 }
1514 
1515 /*
1516  * If shadowing a vnode, apply the VOP_SETATTR to it, and to the fnode.
1517  * Otherwise, set the time and return 0.
1518  */
1519 int
1520 fifo_setattr(
1521         vnode_t                 *vp,
1522         vattr_t                 *vap,
1523         int                     flags,
1524         cred_t                  *crp,
1525         caller_context_t        *ctp)
1526 {
1527         fifonode_t      *fnp    = VTOF(vp);
1528         int             error   = 0;
1529         fifolock_t      *fn_lock;
1530 
1531         if (fnp->fn_realvp)
1532                 error = VOP_SETATTR(fnp->fn_realvp, vap, flags, crp, ctp);
1533         if (error == 0) {
1534                 fn_lock = fnp->fn_lock;
1535                 mutex_enter(&fn_lock->flk_lock);
1536                 if (vap->va_mask & AT_ATIME)
1537                         fnp->fn_atime = vap->va_atime.tv_sec;
1538                 if (vap->va_mask & AT_MTIME)
1539                         fnp->fn_mtime = vap->va_mtime.tv_sec;
1540                 fnp->fn_ctime = gethrestime_sec();
1541                 mutex_exit(&fn_lock->flk_lock);
1542         }
1543         return (error);
1544 }
1545 
1546 /*
1547  * If shadowing a vnode, apply VOP_ACCESS to it.
1548  * Otherwise, return 0 (allow all access).
1549  */
1550 int
1551 fifo_access(vnode_t *vp, int mode, int flags, cred_t *crp, caller_context_t *ct)
1552 {
1553         if (VTOF(vp)->fn_realvp)
1554                 return (VOP_ACCESS(VTOF(vp)->fn_realvp, mode, flags, crp, ct));
1555         else
1556                 return (0);
1557 }
1558 
1559 /*
1560  * This can be called if creat or an open with O_CREAT is done on the root
1561  * of a lofs mount where the mounted entity is a fifo.
1562  */
1563 /*ARGSUSED*/
1564 static int
1565 fifo_create(struct vnode *dvp, char *name, vattr_t *vap, enum vcexcl excl,
1566     int mode, struct vnode **vpp, struct cred *cr, int flag,
1567     caller_context_t *ct, vsecattr_t *vsecp)
1568 {
1569         int error;
1570 
1571         ASSERT(dvp && (dvp->v_flag & VROOT) && *name == '\0');
1572         if (excl == NONEXCL) {
1573                 if (mode && (error = fifo_access(dvp, mode, 0, cr, ct)))
1574                         return (error);
1575                 VN_HOLD(dvp);
1576                 return (0);
1577         }
1578         return (EEXIST);
1579 }
1580 
1581 /*
1582  * If shadowing a vnode, apply the VOP_FSYNC to it.
1583  * Otherwise, return 0.
1584  */
1585 int
1586 fifo_fsync(vnode_t *vp, int syncflag, cred_t *crp, caller_context_t *ct)
1587 {
1588         fifonode_t      *fnp    = VTOF(vp);
1589         vattr_t         va;
1590 
1591         if (fnp->fn_realvp == NULL)
1592                 return (0);
1593 
1594         bzero((caddr_t)&va, sizeof (va));
1595         va.va_mask = AT_MTIME | AT_ATIME;
1596         if (VOP_GETATTR(fnp->fn_realvp, &va, 0, crp, ct) == 0) {
1597                 va.va_mask = 0;
1598                 if (fnp->fn_mtime > va.va_mtime.tv_sec) {
1599                         va.va_mtime.tv_sec = fnp->fn_mtime;
1600                         va.va_mask = AT_MTIME;
1601                 }
1602                 if (fnp->fn_atime > va.va_atime.tv_sec) {
1603                         va.va_atime.tv_sec = fnp->fn_atime;
1604                         va.va_mask |= AT_ATIME;
1605                 }
1606                 if (va.va_mask != 0)
1607                         (void) VOP_SETATTR(fnp->fn_realvp, &va, 0, crp, ct);
1608         }
1609         return (VOP_FSYNC(fnp->fn_realvp, syncflag, crp, ct));
1610 }
1611 
1612 /*
1613  * Called when the upper level no longer holds references to the
1614  * vnode. Sync the file system and free the fifonode.
1615  */
1616 void
1617 fifo_inactive(vnode_t *vp, cred_t *crp, caller_context_t *ct)
1618 {
1619         fifonode_t      *fnp;
1620         fifolock_t      *fn_lock;
1621 
1622         mutex_enter(&ftable_lock);
1623         mutex_enter(&vp->v_lock);
1624         ASSERT(vp->v_count >= 1);
1625         if (--vp->v_count != 0) {
1626                 /*
1627                  * Somebody accessed the fifo before we got a chance to
1628                  * remove it.  They will remove it when they do a vn_rele.
1629                  */
1630                 mutex_exit(&vp->v_lock);
1631                 mutex_exit(&ftable_lock);
1632                 return;
1633         }
1634         mutex_exit(&vp->v_lock);
1635 
1636         fnp = VTOF(vp);
1637 
1638         /*
1639          * remove fifo from fifo list so that no other process
1640          * can grab it.
1641          * Drop the reference count on the fifo node's
1642          * underlying vfs.
1643          */
1644         if (fnp->fn_realvp) {
1645                 (void) fiforemove(fnp);
1646                 mutex_exit(&ftable_lock);
1647                 (void) fifo_fsync(vp, FSYNC, crp, ct);
1648                 VN_RELE(fnp->fn_realvp);
1649                 VFS_RELE(vp->v_vfsp);
1650                 vp->v_vfsp = NULL;
1651         } else
1652                 mutex_exit(&ftable_lock);
1653 
1654         fn_lock = fnp->fn_lock;
1655 
1656         mutex_enter(&fn_lock->flk_lock);
1657         ASSERT(vp->v_stream == NULL);
1658         ASSERT(vp->v_count == 0);
1659         /*
1660          * if this is last reference to the lock, then we can
1661          * free everything up.
1662          */
1663         if (--fn_lock->flk_ref == 0) {
1664                 mutex_exit(&fn_lock->flk_lock);
1665                 ASSERT(fnp->fn_open == 0);
1666                 ASSERT(fnp->fn_dest->fn_open == 0);
1667                 if (fnp->fn_mp) {
1668                         freemsg(fnp->fn_mp);
1669                         fnp->fn_mp = NULL;
1670                         fnp->fn_count = 0;
1671                 }
1672                 if (fnp->fn_pcredp != NULL) {
1673                         crfree(fnp->fn_pcredp);
1674                         fnp->fn_pcredp = NULL;
1675                 }
1676                 if (fnp->fn_flag & ISPIPE) {
1677                         fifonode_t *fn_dest = fnp->fn_dest;
1678 
1679                         vp = FTOV(fn_dest);
1680                         if (fn_dest->fn_mp) {
1681                                 freemsg(fn_dest->fn_mp);
1682                                 fn_dest->fn_mp = NULL;
1683                                 fn_dest->fn_count = 0;
1684                         }
1685                         if (fn_dest->fn_pcredp != NULL) {
1686                                 crfree(fn_dest->fn_pcredp);
1687                                 fn_dest->fn_pcredp = NULL;
1688                         }
1689                         kmem_cache_free(pipe_cache, (fifodata_t *)fn_lock);
1690                 } else
1691                         kmem_cache_free(fnode_cache, (fifodata_t *)fn_lock);
1692         } else {
1693                 mutex_exit(&fn_lock->flk_lock);
1694         }
1695 }
1696 
1697 /*
1698  * If shadowing a vnode, apply the VOP_FID to it.
1699  * Otherwise, return EINVAL.
1700  */
1701 int
1702 fifo_fid(vnode_t *vp, fid_t *fidfnp, caller_context_t *ct)
1703 {
1704         if (VTOF(vp)->fn_realvp)
1705                 return (VOP_FID(VTOF(vp)->fn_realvp, fidfnp, ct));
1706         else
1707                 return (EINVAL);
1708 }
1709 
1710 /*
1711  * Lock a fifonode.
1712  */
1713 /* ARGSUSED */
1714 int
1715 fifo_rwlock(vnode_t *vp, int write_lock, caller_context_t *ctp)
1716 {
1717         return (-1);
1718 }
1719 
1720 /*
1721  * Unlock a fifonode.
1722  */
1723 /* ARGSUSED */
1724 void
1725 fifo_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ctp)
1726 {
1727 }
1728 
1729 /*
1730  * Return error since seeks are not allowed on pipes.
1731  */
1732 /*ARGSUSED*/
1733 int
1734 fifo_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
1735 {
1736         return (ESPIPE);
1737 }
1738 
1739 /*
1740  * If there is a realvp associated with vp, return it.
1741  */
1742 int
1743 fifo_realvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
1744 {
1745         vnode_t *rvp;
1746 
1747         if ((rvp = VTOF(vp)->fn_realvp) != NULL) {
1748                 vp = rvp;
1749                 if (VOP_REALVP(vp, &rvp, ct) == 0)
1750                         vp = rvp;
1751         }
1752 
1753         *vpp = vp;
1754         return (0);
1755 }
1756 
1757 /*
1758  * Poll for interesting events on a stream pipe
1759  */
1760 /* ARGSUSED */
1761 int
1762 fifo_poll(vnode_t *vp, short events, int anyyet, short *reventsp,
1763         pollhead_t **phpp, caller_context_t *ct)
1764 {
1765         fifonode_t      *fnp, *fn_dest;
1766         fifolock_t      *fn_lock;
1767         int             retevents;
1768         struct stdata   *stp;
1769 
1770         ASSERT(vp->v_stream != NULL);
1771 
1772         stp = vp->v_stream;
1773         retevents       = 0;
1774         fnp             = VTOF(vp);
1775         fn_dest         = fnp->fn_dest;
1776         fn_lock         = fnp->fn_lock;
1777 
1778         if (polllock(&stp->sd_pollist, &fn_lock->flk_lock) != 0) {
1779                 *reventsp = POLLNVAL;
1780                 return (0);
1781         }
1782 
1783         /*
1784          * see if FIFO/pipe open
1785          */
1786         if ((fnp->fn_flag & FIFOISOPEN) == 0) {
1787                 if (((events & (POLLIN | POLLRDNORM | POLLPRI | POLLRDBAND)) &&
1788                     fnp->fn_rcnt == 0) ||
1789                     ((events & (POLLWRNORM | POLLWRBAND)) &&
1790                     fnp->fn_wcnt == 0)) {
1791                         mutex_exit(&fnp->fn_lock->flk_lock);
1792                         *reventsp = POLLERR;
1793                         return (0);
1794                 }
1795         }
1796 
1797         /*
1798          * if not in fast mode, let the stream head take care of it
1799          */
1800         if (!(fnp->fn_flag & FIFOFAST)) {
1801                 mutex_exit(&fnp->fn_lock->flk_lock);
1802                 goto stream_mode;
1803         }
1804 
1805         /*
1806          * If this is a pipe.. check to see if the other
1807          * end is gone.  If we are a fifo, check to see
1808          * if write end is gone.
1809          */
1810 
1811         if ((fnp->fn_flag & ISPIPE) && (fn_dest->fn_open == 0)) {
1812                 retevents = POLLHUP;
1813         } else if ((fnp->fn_flag & (FIFOCLOSE | ISPIPE)) == FIFOCLOSE &&
1814             (fn_dest->fn_wcnt == 0)) {
1815                 /*
1816                  * no writer at other end.
1817                  * it was closed (versus yet to be opened)
1818                  */
1819                         retevents = POLLHUP;
1820         } else if (events & (POLLWRNORM | POLLWRBAND)) {
1821                 if (events & POLLWRNORM) {
1822                         if (fn_dest->fn_count < Fifohiwat)
1823                                 retevents = POLLWRNORM;
1824                         else
1825                                 fnp->fn_flag |= FIFOHIWATW;
1826                 }
1827                 /*
1828                  * This is always true for fast pipes
1829                  * (Note: will go to STREAMS mode if band data is written)
1830                  */
1831                 if (events & POLLWRBAND)
1832                         retevents |= POLLWRBAND;
1833         }
1834         if (events & (POLLIN | POLLRDNORM)) {
1835                 if (fnp->fn_count)
1836                         retevents |= (events & (POLLIN | POLLRDNORM));
1837         }
1838 
1839         /*
1840          * if we happened to get something and we're not edge-triggered, return
1841          */
1842         if ((*reventsp = (short)retevents) != 0 && !(events & POLLET)) {
1843                 mutex_exit(&fnp->fn_lock->flk_lock);
1844                 return (0);
1845         }
1846 
1847         /*
1848          * If poll() has not found any events yet or we're edge-triggered, set
1849          * up event cell to wake up the poll if a requested event occurs on this
1850          * pipe/fifo.
1851          */
1852         if (!anyyet) {
1853                 if (events & POLLWRNORM)
1854                         fnp->fn_flag |= FIFOPOLLW;
1855                 if (events & (POLLIN | POLLRDNORM))
1856                         fnp->fn_flag |= FIFOPOLLR;
1857                 if (events & POLLRDBAND)
1858                         fnp->fn_flag |= FIFOPOLLRBAND;
1859                 /*
1860                  * XXX Don't like exposing this from streams
1861                  */
1862                 *phpp = &stp->sd_pollist;
1863         }
1864         mutex_exit(&fnp->fn_lock->flk_lock);
1865         return (0);
1866 stream_mode:
1867         return (strpoll(stp, events, anyyet, reventsp, phpp));
1868 }
1869 
1870 /*
1871  * POSIX pathconf() support.
1872  */
1873 /* ARGSUSED */
1874 int
1875 fifo_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
1876         caller_context_t *ct)
1877 {
1878         ulong_t val;
1879         int error = 0;
1880 
1881         switch (cmd) {
1882 
1883         case _PC_LINK_MAX:
1884                 val = MAXLINK;
1885                 break;
1886 
1887         case _PC_MAX_CANON:
1888                 val = MAX_CANON;
1889                 break;
1890 
1891         case _PC_MAX_INPUT:
1892                 val = MAX_INPUT;
1893                 break;
1894 
1895         case _PC_NAME_MAX:
1896                 error = EINVAL;
1897                 break;
1898 
1899         case _PC_PATH_MAX:
1900         case _PC_SYMLINK_MAX:
1901                 val = MAXPATHLEN;
1902                 break;
1903 
1904         case _PC_PIPE_BUF:
1905                 val = PIPE_BUF;
1906                 break;
1907 
1908         case _PC_NO_TRUNC:
1909                 if (vp->v_vfsp->vfs_flag & VFS_NOTRUNC)
1910                         val = 1;        /* NOTRUNC is enabled for vp */
1911                 else
1912                         val = (ulong_t)-1;
1913                 break;
1914 
1915         case _PC_VDISABLE:
1916                 val = _POSIX_VDISABLE;
1917                 break;
1918 
1919         case _PC_CHOWN_RESTRICTED:
1920                 if (rstchown)
1921                         val = rstchown;         /* chown restricted enabled */
1922                 else
1923                         val = (ulong_t)-1;
1924                 break;
1925 
1926         case _PC_FILESIZEBITS:
1927                 val = (ulong_t)-1;
1928                 break;
1929 
1930         default:
1931                 if (VTOF(vp)->fn_realvp)
1932                         error = VOP_PATHCONF(VTOF(vp)->fn_realvp, cmd,
1933                             &val, cr, ct);
1934                 else
1935                         error = EINVAL;
1936                 break;
1937         }
1938 
1939         if (error == 0)
1940                 *valp = val;
1941         return (error);
1942 }
1943 
1944 /*
1945  * If shadowing a vnode, apply VOP_SETSECATTR to it.
1946  * Otherwise, return NOSYS.
1947  */
1948 int
1949 fifo_setsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *crp,
1950         caller_context_t *ct)
1951 {
1952         int error;
1953 
1954         /*
1955          * The acl(2) system call tries to grab the write lock on the
1956          * file when setting an ACL, but fifofs does not implement
1957          * VOP_RWLOCK or VOP_RWUNLOCK, so we do it here instead.
1958          */
1959         if (VTOF(vp)->fn_realvp) {
1960                 (void) VOP_RWLOCK(VTOF(vp)->fn_realvp, V_WRITELOCK_TRUE, ct);
1961                 error = VOP_SETSECATTR(VTOF(vp)->fn_realvp, vsap, flag,
1962                     crp, ct);
1963                 VOP_RWUNLOCK(VTOF(vp)->fn_realvp, V_WRITELOCK_TRUE, ct);
1964                 return (error);
1965         } else
1966                 return (fs_nosys());
1967 }
1968 
1969 /*
1970  * If shadowing a vnode, apply VOP_GETSECATTR to it. Otherwise, fabricate
1971  * an ACL from the permission bits that fifo_getattr() makes up.
1972  */
1973 int
1974 fifo_getsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *crp,
1975         caller_context_t *ct)
1976 {
1977         if (VTOF(vp)->fn_realvp)
1978                 return (VOP_GETSECATTR(VTOF(vp)->fn_realvp, vsap, flag,
1979                     crp, ct));
1980         else
1981                 return (fs_fab_acl(vp, vsap, flag, crp, ct));
1982 }
1983 
1984 
1985 /*
1986  * Set the FIFOSTAYFAST flag so nobody can turn the fifo into stream mode.
1987  * If the flag is already set then wait until it is removed - releasing
1988  * the lock.
1989  * If the fifo switches into stream mode while we are waiting, return failure.
1990  */
1991 static boolean_t
1992 fifo_stayfast_enter(fifonode_t *fnp)
1993 {
1994         ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock));
1995         while (fnp->fn_flag & FIFOSTAYFAST) {
1996                 fnp->fn_flag |= FIFOWAITMODE;
1997                 cv_wait(&fnp->fn_wait_cv, &fnp->fn_lock->flk_lock);
1998                 fnp->fn_flag &= ~FIFOWAITMODE;
1999         }
2000         if (!(fnp->fn_flag & FIFOFAST))
2001                 return (B_FALSE);
2002 
2003         fnp->fn_flag |= FIFOSTAYFAST;
2004         return (B_TRUE);
2005 }
2006 
2007 /*
2008  * Unset the FIFOSTAYFAST flag and notify anybody waiting for this flag
2009  * to be removed:
2010  *      - threads wanting to turn into stream mode waiting in fifo_fastoff(),
2011  *      - other writers threads waiting in fifo_stayfast_enter().
2012  */
2013 static void
2014 fifo_stayfast_exit(fifonode_t *fnp)
2015 {
2016         fifonode_t *fn_dest = fnp->fn_dest;
2017 
2018         ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock));
2019 
2020         fnp->fn_flag &= ~FIFOSTAYFAST;
2021 
2022         if (fnp->fn_flag & FIFOWAITMODE)
2023                 cv_broadcast(&fnp->fn_wait_cv);
2024 
2025         if ((fnp->fn_flag & ISPIPE) && (fn_dest->fn_flag & FIFOWAITMODE))
2026                 cv_broadcast(&fn_dest->fn_wait_cv);
2027 }