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 
  23 /*
  24  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  25  */
  26 
  27 /*
  28  * The routines defined in this file are supporting routines for FIFOFS
  29  * file system type.
  30  */
  31 #include <sys/types.h>
  32 #include <sys/param.h>
  33 #include <sys/systm.h>
  34 #include <sys/debug.h>
  35 #include <sys/errno.h>
  36 #include <sys/time.h>
  37 #include <sys/kmem.h>
  38 #include <sys/inline.h>
  39 #include <sys/file.h>
  40 #include <sys/proc.h>
  41 #include <sys/stat.h>
  42 #include <sys/sysmacros.h>
  43 #include <sys/var.h>
  44 #include <sys/vfs.h>
  45 #include <sys/vfs_opreg.h>
  46 #include <sys/vnode.h>
  47 #include <sys/mode.h>
  48 #include <sys/signal.h>
  49 #include <sys/user.h>
  50 #include <sys/uio.h>
  51 #include <sys/flock.h>
  52 #include <sys/stream.h>
  53 #include <sys/fs/fifonode.h>
  54 #include <sys/strsubr.h>
  55 #include <sys/stropts.h>
  56 #include <sys/cmn_err.h>
  57 #include <fs/fs_subr.h>
  58 #include <sys/ddi.h>
  59 
  60 
  61 #if FIFODEBUG
  62 int Fifo_fastmode = 1;          /* pipes/fifos will be opened in fast mode */
  63 int Fifo_verbose = 0;           /* msg when switching out of fast mode */
  64 int Fifohiwat = FIFOHIWAT;      /* Modifiable FIFO high water mark */
  65 #endif
  66 
  67 /*
  68  * This is the loadable module wrapper.
  69  */
  70 #include <sys/modctl.h>
  71 
  72 extern struct qinit fifo_strdata;
  73 
  74 struct vfsops *fifo_vfsops;
  75 
  76 static vfsdef_t vfw = {
  77         VFSDEF_VERSION,
  78         "fifofs",
  79         fifoinit,
  80         VSW_ZMOUNT,
  81         NULL
  82 };
  83 
  84 /*
  85  * Module linkage information for the kernel.
  86  */
  87 extern struct mod_ops mod_fsops;
  88 
  89 static struct modlfs modlfs = {
  90         &mod_fsops, "filesystem for fifo", &vfw
  91 };
  92 
  93 static struct modlinkage modlinkage = {
  94         MODREV_1, (void *)&modlfs, NULL
  95 };
  96 
  97 int
  98 _init()
  99 {
 100         return (mod_install(&modlinkage));
 101 }
 102 
 103 int
 104 _info(struct modinfo *modinfop)
 105 {
 106         return (mod_info(&modlinkage, modinfop));
 107 }
 108 
 109 /*
 110  * Define data structures within this file.
 111  * XXX should the hash size be configurable ?
 112  */
 113 #define FIFOSHFT        5
 114 #define FIFO_HASHSZ     63
 115 
 116 #if ((FIFO_HASHSZ & (FIFO_HASHSZ - 1)) == 0)
 117 #define FIFOHASH(vp) (((uintptr_t)(vp) >> FIFOSHFT) & (FIFO_HASHSZ - 1))
 118 #else
 119 #define FIFOHASH(vp) (((uintptr_t)(vp) >> FIFOSHFT) % FIFO_HASHSZ)
 120 #endif
 121 
 122 fifonode_t      *fifoalloc[FIFO_HASHSZ];
 123 dev_t           fifodev;
 124 struct vfs      *fifovfsp;
 125 int             fifofstype;
 126 
 127 kmutex_t ftable_lock;
 128 static kmutex_t fino_lock;
 129 struct kmem_cache *fnode_cache;
 130 struct kmem_cache *pipe_cache;
 131 
 132 static void fifoinsert(fifonode_t *);
 133 static fifonode_t *fifofind(vnode_t *);
 134 static int fifo_connld(struct vnode **, int, cred_t *);
 135 static void fifo_fastturnoff(fifonode_t *);
 136 
 137 static void fifo_reinit_vp(vnode_t *);
 138 
 139 static void fnode_destructor(void *, void *);
 140 
 141 /*
 142  * Constructor/destructor routines for fifos and pipes.
 143  *
 144  * In the interest of code sharing, we define a common fifodata structure
 145  * which consists of a fifolock and one or two fnodes.  A fifo contains
 146  * one fnode; a pipe contains two.  The fifolock is shared by the fnodes,
 147  * each of which points to it:
 148  *
 149  *      --> -->   ---------  --- ---
 150  *      |   |   | lock  |   |   |
 151  *      |   |   ---------   |   |
 152  *      |   |   |       |  fifo |
 153  *      |   --- | fnode |   |   |
 154  *      |       |       |   |  pipe
 155  *      |       ---------  ---  |
 156  *      |       |       |       |
 157  *      ------- | fnode |       |
 158  *              |       |       |
 159  *              ---------      ---
 160  *
 161  * Since the fifolock is at the beginning of the fifodata structure,
 162  * the fifolock address is the same as the fifodata address.  Thus,
 163  * we can determine the fifodata address from any of its member fnodes.
 164  * This is essential for fifo_inactive.
 165  *
 166  * The fnode constructor is designed to handle any fifodata structure,
 167  * deducing the number of fnodes from the total size.  Thus, the fnode
 168  * constructor does most of the work for the pipe constructor.
 169  */
 170 static int
 171 fnode_constructor(void *buf, void *cdrarg, int kmflags)
 172 {
 173         fifodata_t *fdp = buf;
 174         fifolock_t *flp = &fdp->fifo_lock;
 175         fifonode_t *fnp = &fdp->fifo_fnode[0];
 176         size_t size = (uintptr_t)cdrarg;
 177 
 178         mutex_init(&flp->flk_lock, NULL, MUTEX_DEFAULT, NULL);
 179         cv_init(&flp->flk_wait_cv, NULL, CV_DEFAULT, NULL);
 180         flp->flk_ocsync = 0;
 181 
 182         while ((char *)fnp < (char *)buf + size) {
 183 
 184                 vnode_t *vp;
 185 
 186                 vp = vn_alloc(kmflags);
 187                 if (vp == NULL) {
 188                         fnp->fn_vnode = NULL; /* mark for destructor */
 189                         fnode_destructor(buf, cdrarg);
 190                         return (-1);
 191                 }
 192                 fnp->fn_vnode = vp;
 193 
 194                 fnp->fn_lock = flp;
 195                 fnp->fn_open = 0;
 196                 fnp->fn_dest = fnp;
 197                 fnp->fn_mp = NULL;
 198                 fnp->fn_count = 0;
 199                 fnp->fn_rsynccnt = 0;
 200                 fnp->fn_wsynccnt = 0;
 201                 fnp->fn_wwaitcnt = 0;
 202                 fnp->fn_insync = 0;
 203                 fnp->fn_pcredp = NULL;
 204                 fnp->fn_cpid = -1;
 205                 /*
 206                  * 32-bit stat(2) may fail if fn_ino isn't initialized
 207                  */
 208                 fnp->fn_ino = 0;
 209 
 210                 cv_init(&fnp->fn_wait_cv, NULL, CV_DEFAULT, NULL);
 211 
 212                 vn_setops(vp, fifo_vnodeops);
 213                 vp->v_stream = NULL;
 214                 vp->v_type = VFIFO;
 215                 vp->v_data = (caddr_t)fnp;
 216                 vp->v_flag = VNOMAP | VNOSWAP;
 217                 vn_exists(vp);
 218                 fnp++;
 219         }
 220         return (0);
 221 }
 222 
 223 static void
 224 fnode_destructor(void *buf, void *cdrarg)
 225 {
 226         fifodata_t *fdp = buf;
 227         fifolock_t *flp = &fdp->fifo_lock;
 228         fifonode_t *fnp = &fdp->fifo_fnode[0];
 229         size_t size = (uintptr_t)cdrarg;
 230 
 231         mutex_destroy(&flp->flk_lock);
 232         cv_destroy(&flp->flk_wait_cv);
 233         ASSERT(flp->flk_ocsync == 0);
 234 
 235         while ((char *)fnp < (char *)buf + size) {
 236 
 237                 vnode_t *vp = FTOV(fnp);
 238 
 239                 if (vp == NULL) {
 240                         return; /* constructor failed here */
 241                 }
 242 
 243                 ASSERT(fnp->fn_mp == NULL);
 244                 ASSERT(fnp->fn_count == 0);
 245                 ASSERT(fnp->fn_lock == flp);
 246                 ASSERT(fnp->fn_open == 0);
 247                 ASSERT(fnp->fn_insync == 0);
 248                 ASSERT(fnp->fn_rsynccnt == 0 && fnp->fn_wsynccnt == 0);
 249                 ASSERT(fnp->fn_wwaitcnt == 0);
 250                 ASSERT(fnp->fn_pcredp == NULL);
 251                 ASSERT(vn_matchops(vp, fifo_vnodeops));
 252                 ASSERT(vp->v_stream == NULL);
 253                 ASSERT(vp->v_type == VFIFO);
 254                 ASSERT(vp->v_data == (caddr_t)fnp);
 255                 ASSERT((vp->v_flag & (VNOMAP|VNOSWAP)) == (VNOMAP|VNOSWAP));
 256 
 257                 cv_destroy(&fnp->fn_wait_cv);
 258                 vn_invalid(vp);
 259                 vn_free(vp);
 260 
 261                 fnp++;
 262         }
 263 }
 264 
 265 static int
 266 pipe_constructor(void *buf, void *cdrarg, int kmflags)
 267 {
 268         fifodata_t *fdp = buf;
 269         fifonode_t *fnp1 = &fdp->fifo_fnode[0];
 270         fifonode_t *fnp2 = &fdp->fifo_fnode[1];
 271         vnode_t *vp1;
 272         vnode_t *vp2;
 273 
 274         (void) fnode_constructor(buf, cdrarg, kmflags);
 275 
 276         vp1 = FTOV(fnp1);
 277         vp2 = FTOV(fnp2);
 278 
 279         vp1->v_vfsp  = vp2->v_vfsp                = fifovfsp;
 280         vp1->v_rdev  = vp2->v_rdev                = fifodev;
 281         fnp1->fn_realvp      = fnp2->fn_realvp    = NULL;
 282         fnp1->fn_dest        = fnp2;
 283         fnp2->fn_dest        = fnp1;
 284 
 285         return (0);
 286 }
 287 
 288 static void
 289 pipe_destructor(void *buf, void *cdrarg)
 290 {
 291 #ifdef DEBUG
 292         fifodata_t *fdp = buf;
 293         fifonode_t *fnp1 = &fdp->fifo_fnode[0];
 294         fifonode_t *fnp2 = &fdp->fifo_fnode[1];
 295         vnode_t *vp1 = FTOV(fnp1);
 296         vnode_t *vp2 = FTOV(fnp2);
 297 
 298         ASSERT(vp1->v_vfsp == fifovfsp);
 299         ASSERT(vp2->v_vfsp == fifovfsp);
 300         ASSERT(vp1->v_rdev == fifodev);
 301         ASSERT(vp2->v_rdev == fifodev);
 302 #endif
 303         fnode_destructor(buf, cdrarg);
 304 }
 305 
 306 /*
 307  * Reinitialize a FIFO vnode (uses normal vnode reinit, but ensures that
 308  * vnode type and flags are reset).
 309  */
 310 
 311 static void fifo_reinit_vp(vnode_t *vp)
 312 {
 313         vn_reinit(vp);
 314         vp->v_type = VFIFO;
 315         vp->v_flag &= VROOT;
 316         vp->v_flag |= VNOMAP | VNOSWAP;
 317 }
 318 
 319 /*
 320  * Save file system type/index, initialize vfs operations vector, get
 321  * unique device number for FIFOFS and initialize the FIFOFS hash.
 322  * Create and initialize a "generic" vfs pointer that will be placed
 323  * in the v_vfsp field of each pipe's vnode.
 324  */
 325 int
 326 fifoinit(int fstype, char *name)
 327 {
 328         static const fs_operation_def_t fifo_vfsops_template[] = {
 329                 NULL, NULL
 330         };
 331         int error;
 332         major_t dev;
 333 
 334         fifofstype = fstype;
 335         error = vfs_setfsops(fstype, fifo_vfsops_template, &fifo_vfsops);
 336         if (error != 0) {
 337                 cmn_err(CE_WARN, "fifoinit: bad vfs ops template");
 338                 return (error);
 339         }
 340 
 341         error = vn_make_ops(name, fifo_vnodeops_template, &fifo_vnodeops);
 342         if (error != 0) {
 343                 (void) vfs_freevfsops_by_type(fstype);
 344                 cmn_err(CE_WARN, "fifoinit: bad vnode ops template");
 345                 return (error);
 346         }
 347 
 348         if ((dev = getudev()) == (major_t)-1) {
 349                 cmn_err(CE_WARN, "fifoinit: can't get unique device number");
 350                 dev = 0;
 351         }
 352         fifodev = makedevice(dev, 0);
 353 
 354         fifovfsp = kmem_zalloc(sizeof (struct vfs), KM_SLEEP);
 355         fifovfsp->vfs_next = NULL;
 356         vfs_setops(fifovfsp, fifo_vfsops);
 357         fifovfsp->vfs_vnodecovered = NULL;
 358         fifovfsp->vfs_flag = 0;
 359         fifovfsp->vfs_bsize = 1024;
 360         fifovfsp->vfs_fstype = fifofstype;
 361         vfs_make_fsid(&fifovfsp->vfs_fsid, fifodev, fifofstype);
 362         fifovfsp->vfs_data = NULL;
 363         fifovfsp->vfs_dev = fifodev;
 364         fifovfsp->vfs_bcount = 0;
 365 
 366         /*
 367          * It is necessary to initialize vfs_count here to 1.
 368          * This prevents the fifovfsp from getting freed when
 369          * a thread does a VFS_HOLD followed by a VFS_RELE
 370          * on the fifovfsp
 371          *
 372          * The fifovfsp should never be freed.
 373          */
 374         fifovfsp->vfs_count = 1;
 375 
 376         mutex_init(&ftable_lock, NULL, MUTEX_DEFAULT, NULL);
 377         mutex_init(&fino_lock, NULL, MUTEX_DEFAULT, NULL);
 378 
 379         /*
 380          * vnodes are cached aligned
 381          */
 382         fnode_cache = kmem_cache_create("fnode_cache",
 383             sizeof (fifodata_t) - sizeof (fifonode_t), 32,
 384             fnode_constructor, fnode_destructor, NULL,
 385             (void *)(sizeof (fifodata_t) - sizeof (fifonode_t)), NULL, 0);
 386 
 387         pipe_cache = kmem_cache_create("pipe_cache", sizeof (fifodata_t), 32,
 388             pipe_constructor, pipe_destructor, NULL,
 389             (void *)(sizeof (fifodata_t)), NULL, 0);
 390 
 391 #if FIFODEBUG
 392         if (Fifohiwat < FIFOHIWAT)
 393                 Fifohiwat = FIFOHIWAT;
 394 #endif /* FIFODEBUG */
 395         fifo_strdata.qi_minfo->mi_hiwat = Fifohiwat;
 396 
 397         return (0);
 398 }
 399 
 400 /*
 401  * Provide a shadow for a vnode.  We create a new shadow before checking for an
 402  * existing one, to minimize the amount of time we need to hold ftable_lock.
 403  * If a vp already has a shadow in the hash list, return its shadow.  If not,
 404  * we hash the new vnode and return its pointer to the caller.
 405  */
 406 vnode_t *
 407 fifovp(vnode_t *vp, cred_t *crp)
 408 {
 409         fifonode_t *fnp;
 410         fifonode_t *spec_fnp;   /* Speculative fnode ptr. */
 411         fifodata_t *fdp;
 412         vnode_t *newvp;
 413         struct vattr va;
 414         vnode_t *rvp;
 415 
 416         ASSERT(vp != NULL);
 417 
 418         fdp = kmem_cache_alloc(fnode_cache, KM_SLEEP);
 419 
 420         fdp->fifo_lock.flk_ref = 1;
 421         fnp = &fdp->fifo_fnode[0];
 422 
 423         /*
 424          * Its possible that fifo nodes on different lofs mountpoints
 425          * shadow the same real filesystem fifo node.
 426          * In this case its necessary to get and store the realvp.
 427          * This way different fifo nodes sharing the same real vnode
 428          * can use realvp for communication.
 429          */
 430 
 431         if (VOP_REALVP(vp, &rvp, NULL) == 0)
 432                         vp = rvp;
 433 
 434         fnp->fn_realvp       = vp;
 435         fnp->fn_wcnt = 0;
 436         fnp->fn_rcnt = 0;
 437 
 438 #if FIFODEBUG
 439         if (! Fifo_fastmode) {
 440                 fnp->fn_flag = 0;
 441         } else {
 442                 fnp->fn_flag = FIFOFAST;
 443         }
 444 #else /* FIFODEBUG */
 445         fnp->fn_flag = FIFOFAST;
 446 #endif /* FIFODEBUG */
 447 
 448         /*
 449          * initialize the times from vp.
 450          */
 451         va.va_mask = AT_TIMES;
 452         if (VOP_GETATTR(vp, &va, 0, crp, NULL) == 0) {
 453                 fnp->fn_atime = va.va_atime.tv_sec;
 454                 fnp->fn_mtime = va.va_mtime.tv_sec;
 455                 fnp->fn_ctime = va.va_ctime.tv_sec;
 456         } else {
 457                 fnp->fn_atime = 0;
 458                 fnp->fn_mtime = 0;
 459                 fnp->fn_ctime = 0;
 460         }
 461 
 462         /*
 463          * Grab the VP here to avoid holding locks
 464          * whilst trying to acquire others.
 465          */
 466 
 467         VN_HOLD(vp);
 468 
 469         mutex_enter(&ftable_lock);
 470 
 471         if ((spec_fnp = fifofind(vp)) != NULL) {
 472                 mutex_exit(&ftable_lock);
 473 
 474                 /*
 475                  * Release the vnode and free up our pre-prepared fnode.
 476                  * Zero the lock reference just to explicitly signal
 477                  * this is unused.
 478                  */
 479                 VN_RELE(vp);
 480                 fdp->fifo_lock.flk_ref = 0;
 481                 kmem_cache_free(fnode_cache, fdp);
 482 
 483                 return (FTOV(spec_fnp));
 484         }
 485 
 486         newvp = FTOV(fnp);
 487         fifo_reinit_vp(newvp);
 488         /*
 489          * Since the fifo vnode's v_vfsp needs to point to the
 490          * underlying filesystem's vfsp we need to bump up the
 491          * underlying filesystem's vfs reference count.
 492          * The count is decremented when the fifo node is
 493          * inactivated.
 494          */
 495 
 496         VFS_HOLD(vp->v_vfsp);
 497         newvp->v_vfsp = vp->v_vfsp;
 498         newvp->v_rdev = vp->v_rdev;
 499         newvp->v_flag |= (vp->v_flag & VROOT);
 500 
 501         fifoinsert(fnp);
 502         mutex_exit(&ftable_lock);
 503 
 504         return (newvp);
 505 }
 506 
 507 /*
 508  * Create a pipe end by...
 509  * allocating a vnode-fifonode pair and initializing the fifonode.
 510  */
 511 void
 512 makepipe(vnode_t **vpp1, vnode_t **vpp2)
 513 {
 514         fifonode_t *fnp1;
 515         fifonode_t *fnp2;
 516         vnode_t *nvp1;
 517         vnode_t *nvp2;
 518         fifodata_t *fdp;
 519         time_t now;
 520 
 521         fdp = kmem_cache_alloc(pipe_cache, KM_SLEEP);
 522         fdp->fifo_lock.flk_ref = 2;
 523         fnp1 = &fdp->fifo_fnode[0];
 524         fnp2 = &fdp->fifo_fnode[1];
 525 
 526         fnp1->fn_wcnt        = fnp2->fn_wcnt              = 1;
 527         fnp1->fn_rcnt        = fnp2->fn_rcnt              = 1;
 528 #if FIFODEBUG
 529         if (! Fifo_fastmode) {
 530                 fnp1->fn_flag        = fnp2->fn_flag              = ISPIPE;
 531         } else {
 532                 fnp1->fn_flag        = fnp2->fn_flag              = ISPIPE | FIFOFAST;
 533         }
 534 #else /* FIFODEBUG */
 535         fnp1->fn_flag        = fnp2->fn_flag              = ISPIPE | FIFOFAST;
 536 #endif /* FIFODEBUG */
 537         now = gethrestime_sec();
 538         fnp1->fn_atime       = fnp2->fn_atime     = now;
 539         fnp1->fn_mtime       = fnp2->fn_mtime     = now;
 540         fnp1->fn_ctime       = fnp2->fn_ctime     = now;
 541 
 542         *vpp1 = nvp1 = FTOV(fnp1);
 543         *vpp2 = nvp2 = FTOV(fnp2);
 544 
 545         fifo_reinit_vp(nvp1);           /* Reinitialize vnodes for reuse... */
 546         fifo_reinit_vp(nvp2);
 547         nvp1->v_vfsp = fifovfsp;     /* Need to re-establish VFS & device */
 548         nvp2->v_vfsp = fifovfsp;     /* before we can reuse this vnode. */
 549         nvp1->v_rdev = fifodev;
 550         nvp2->v_rdev = fifodev;
 551 }
 552 
 553 /*
 554  * Attempt to establish a unique pipe id.  Only un-named pipes use this
 555  * routine.
 556  */
 557 ino_t
 558 fifogetid(void)
 559 {
 560         static ino_t fifo_ino = 0;
 561         ino_t fino;
 562 
 563         mutex_enter(&fino_lock);
 564         fino = fifo_ino++;
 565         mutex_exit(&fino_lock);
 566         return (fino);
 567 }
 568 
 569 
 570 /*
 571  * Stream a pipe/FIFO.
 572  * The FIFOCONNLD flag is used when CONNLD has been pushed on the stream.
 573  * If the flag is set, a new vnode is created by calling fifo_connld().
 574  * Connld logic was moved to fifo_connld() to speed up the open
 575  * operation, simplify the connld/fifo interaction, and remove inherent
 576  * race conditions between the connld module and fifos.
 577  * This routine is single threaded for two reasons.
 578  * 1) connld requests are synchronous; that is, they must block
 579  *    until the server does an I_RECVFD (oh, well).  Single threading is
 580  *    the simplest way to accomplish this.
 581  * 2) fifo_close() must not send M_HANGUP or M_ERROR while we are
 582  *    in stropen. Stropen() has a tendency to reset things and
 583  *    we would like streams to remember that a hangup occurred.
 584  */
 585 int
 586 fifo_stropen(vnode_t **vpp, int flag, cred_t *crp, int dotwist, int lockheld)
 587 {
 588         int error = 0;
 589         vnode_t *oldvp = *vpp;
 590         fifonode_t *fnp = VTOF(*vpp);
 591         dev_t pdev = 0;
 592         int firstopen = 0;
 593         fifolock_t *fn_lock;
 594 
 595         fn_lock = fnp->fn_lock;
 596         if (!lockheld)
 597                 mutex_enter(&fn_lock->flk_lock);
 598         ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock));
 599 
 600         /*
 601          * FIFO is in the process of opening. Wait for it
 602          * to complete before starting another open on it
 603          * This prevents races associated with connld open
 604          */
 605         while (fnp->fn_flag & FIFOOPEN) {
 606                 if (!cv_wait_sig(&fnp->fn_wait_cv, &fn_lock->flk_lock)) {
 607                         fifo_cleanup(oldvp, flag);
 608                         if (!lockheld)
 609                                 mutex_exit(&fn_lock->flk_lock);
 610                         return (EINTR);
 611                 }
 612         }
 613 
 614         /*
 615          * The other end of the pipe is almost closed so
 616          * reject any other open on this end of the pipe
 617          * This normally only happens with a pipe mounted under namefs, but
 618          * we can also see an open via proc/fd, which should still succeed.
 619          * To indicate the proc/fd case the FKLYR flag is passed.
 620          */
 621         if ((fnp->fn_flag & (FIFOCLOSE|ISPIPE)) == (FIFOCLOSE|ISPIPE) &&
 622             (flag & FKLYR) == 0) {
 623                 fifo_cleanup(oldvp, flag);
 624                 cv_broadcast(&fnp->fn_wait_cv);
 625                 if (!lockheld)
 626                         mutex_exit(&fn_lock->flk_lock);
 627                 return (ENXIO);
 628         }
 629 
 630         fnp->fn_flag |= FIFOOPEN;
 631 
 632         /*
 633          * can't allow close to happen while we are
 634          * in the middle of stropen().
 635          * M_HANGUP and M_ERROR could leave the stream in a strange state
 636          */
 637         while (fn_lock->flk_ocsync)
 638                 cv_wait(&fn_lock->flk_wait_cv, &fn_lock->flk_lock);
 639 
 640         fn_lock->flk_ocsync = 1;
 641 
 642         if (fnp->fn_flag & FIFOCONNLD) {
 643                 /*
 644                  * This is a reopen, so we should release the fifo lock
 645                  * just in case some strange module pushed on connld
 646                  * has some odd side effect.
 647                  * Note: this stropen is on the oldvp.  It will
 648                  * have no impact on the connld vp returned and
 649                  * strclose() will only be called when we release
 650                  * flk_ocsync
 651                  */
 652                 mutex_exit(&fn_lock->flk_lock);
 653                 if ((error = stropen(oldvp, &pdev, flag, crp)) != 0) {
 654                         mutex_enter(&fn_lock->flk_lock);
 655                         fifo_cleanup(oldvp, flag);
 656                         fn_lock->flk_ocsync = 0;
 657                         cv_broadcast(&fn_lock->flk_wait_cv);
 658                         goto out;
 659                 }
 660                 /*
 661                  * streams open done, allow close on other end if
 662                  * required.  Do this now.. it could
 663                  * be a very long time before fifo_connld returns.
 664                  */
 665                 mutex_enter(&fn_lock->flk_lock);
 666                 /*
 667                  * we need to fake an open here so that if this
 668                  * end of the pipe closes, we don't loose the
 669                  * stream head (kind of like single threading
 670                  * open and close for this end of the pipe)
 671                  * We'll need to call fifo_close() to do clean
 672                  * up in case this end of the pipe was closed
 673                  * down while we were in fifo_connld()
 674                  */
 675                 ASSERT(fnp->fn_open > 0);
 676                 fnp->fn_open++;
 677                 fn_lock->flk_ocsync = 0;
 678                 cv_broadcast(&fn_lock->flk_wait_cv);
 679                 mutex_exit(&fn_lock->flk_lock);
 680                 /*
 681                  * Connld has been pushed onto the pipe
 682                  * Create new pipe on behalf of connld
 683                  */
 684                 if (error = fifo_connld(vpp, flag, crp)) {
 685                         (void) fifo_close(oldvp, flag, 1, 0, crp, NULL);
 686                         mutex_enter(&fn_lock->flk_lock);
 687                         goto out;
 688                 }
 689                 /*
 690                  * undo fake open.  We need to call fifo_close
 691                  * because some other thread could have done
 692                  * a close and detach of the named pipe while
 693                  * we were in fifo_connld(), so
 694                  * we want to make sure the close completes (yuk)
 695                  */
 696                 (void) fifo_close(oldvp, flag, 1, 0, crp, NULL);
 697                 /*
 698                  * fifo_connld has changed the vp, so we
 699                  * need to re-initialize locals
 700                  */
 701                 fnp = VTOF(*vpp);
 702                 fn_lock = fnp->fn_lock;
 703                 mutex_enter(&fn_lock->flk_lock);
 704         } else {
 705                 /*
 706                  * release lock in case there are modules pushed that
 707                  * could have some strange side effect
 708                  */
 709 
 710                 mutex_exit(&fn_lock->flk_lock);
 711 
 712                 /*
 713                  * If this is the first open of a fifo (dotwist
 714                  * will be non-zero) we will need to twist the queues.
 715                  */
 716                 if (oldvp->v_stream == NULL)
 717                         firstopen = 1;
 718 
 719 
 720                 /*
 721                  * normal open of pipe/fifo
 722                  */
 723 
 724                 if ((error = stropen(oldvp, &pdev, flag, crp)) != 0) {
 725                         mutex_enter(&fn_lock->flk_lock);
 726                         fifo_cleanup(oldvp, flag);
 727                         ASSERT(fnp->fn_open != 0 || oldvp->v_stream == NULL);
 728                         fn_lock->flk_ocsync = 0;
 729                         cv_broadcast(&fn_lock->flk_wait_cv);
 730                         goto out;
 731                 }
 732                 mutex_enter(&fn_lock->flk_lock);
 733 
 734                 /*
 735                  * twist the ends of the fifo together
 736                  */
 737                 if (dotwist && firstopen)
 738                         strmate(*vpp, *vpp);
 739 
 740                 /*
 741                  * Show that this open has succeeded
 742                  * and allow closes or other opens to proceed
 743                  */
 744                 fnp->fn_open++;
 745                 fn_lock->flk_ocsync = 0;
 746                 cv_broadcast(&fn_lock->flk_wait_cv);
 747         }
 748 out:
 749         fnp->fn_flag &= ~FIFOOPEN;
 750         if (error == 0) {
 751                 fnp->fn_flag |= FIFOISOPEN;
 752                 /*
 753                  * If this is a FIFO and has the close flag set
 754                  * and there are now writers, clear the close flag
 755                  * Note: close flag only gets set when last writer
 756                  * on a FIFO goes away.
 757                  */
 758                 if (((fnp->fn_flag & (ISPIPE|FIFOCLOSE)) == FIFOCLOSE) &&
 759                     fnp->fn_wcnt > 0)
 760                         fnp->fn_flag &= ~FIFOCLOSE;
 761         }
 762         cv_broadcast(&fnp->fn_wait_cv);
 763         if (!lockheld)
 764                 mutex_exit(&fn_lock->flk_lock);
 765         return (error);
 766 }
 767 
 768 /*
 769  * Clean up the state of a FIFO and/or mounted pipe in the
 770  * event that a fifo_open() was interrupted while the
 771  * process was blocked.
 772  */
 773 void
 774 fifo_cleanup(vnode_t *vp, int flag)
 775 {
 776         fifonode_t *fnp = VTOF(vp);
 777 
 778         ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock));
 779 
 780         cleanlocks(vp, curproc->p_pid, 0);
 781         cleanshares(vp, curproc->p_pid);
 782         if (flag & FREAD) {
 783                 fnp->fn_rcnt--;
 784         }
 785         if (flag & FWRITE) {
 786                 fnp->fn_wcnt--;
 787         }
 788         cv_broadcast(&fnp->fn_wait_cv);
 789 }
 790 
 791 
 792 /*
 793  * Insert a fifonode-vnode pair onto the fifoalloc hash list.
 794  */
 795 static void
 796 fifoinsert(fifonode_t *fnp)
 797 {
 798         int idx = FIFOHASH(fnp->fn_realvp);
 799 
 800         /*
 801          * We don't need to hold fn_lock since we're holding ftable_lock and
 802          * this routine is only called right after we've allocated an fnode.
 803          * FIFO is inserted at head of NULL terminated doubly linked list.
 804          */
 805 
 806         ASSERT(MUTEX_HELD(&ftable_lock));
 807         fnp->fn_backp = NULL;
 808         fnp->fn_nextp = fifoalloc[idx];
 809         fifoalloc[idx] = fnp;
 810         if (fnp->fn_nextp)
 811                 fnp->fn_nextp->fn_backp = fnp;
 812 }
 813 
 814 /*
 815  * Find a fifonode-vnode pair on the fifoalloc hash list.
 816  * vp is a vnode to be shadowed. If it's on the hash list,
 817  * it already has a shadow, therefore return its corresponding
 818  * fifonode.
 819  */
 820 static fifonode_t *
 821 fifofind(vnode_t *vp)
 822 {
 823         fifonode_t *fnode;
 824 
 825         ASSERT(MUTEX_HELD(&ftable_lock));
 826         for (fnode = fifoalloc[FIFOHASH(vp)]; fnode; fnode = fnode->fn_nextp) {
 827                 if (fnode->fn_realvp == vp) {
 828                         VN_HOLD(FTOV(fnode));
 829                         return (fnode);
 830                 }
 831         }
 832         return (NULL);
 833 }
 834 
 835 /*
 836  * Remove a fifonode-vnode pair from the fifoalloc hash list.
 837  * This routine is called from the fifo_inactive() routine when a
 838  * FIFO is being released.
 839  * If the link to be removed is the only link, set fifoalloc to NULL.
 840  */
 841 void
 842 fiforemove(fifonode_t *fnp)
 843 {
 844         int idx = FIFOHASH(fnp->fn_realvp);
 845         fifonode_t *fnode;
 846 
 847         ASSERT(MUTEX_HELD(&ftable_lock));
 848         fnode = fifoalloc[idx];
 849         /*
 850          * fast path... only 1 FIFO in this list entry
 851          */
 852         if (fnode != NULL && fnode == fnp &&
 853             !fnode->fn_nextp && !fnode->fn_backp) {
 854                 fifoalloc[idx] = NULL;
 855         } else {
 856 
 857                 for (;  fnode;  fnode = fnode->fn_nextp) {
 858                         if (fnode == fnp) {
 859                                 /*
 860                                  * if we are first entry
 861                                  */
 862                                 if (fnp == fifoalloc[idx])
 863                                         fifoalloc[idx] = fnp->fn_nextp;
 864                                 if (fnode->fn_nextp)
 865                                         fnode->fn_nextp->fn_backp =
 866                                             fnode->fn_backp;
 867                                 if (fnode->fn_backp)
 868                                         fnode->fn_backp->fn_nextp =
 869                                             fnode->fn_nextp;
 870                                 break;
 871                         }
 872                 }
 873         }
 874 }
 875 
 876 /*
 877  * Flush all data from a fifo's message queue
 878  */
 879 
 880 void
 881 fifo_fastflush(fifonode_t *fnp)
 882 {
 883         mblk_t *bp;
 884         ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock));
 885 
 886         if ((bp = fnp->fn_mp) != NULL) {
 887                 fnp->fn_mp = NULL;
 888                 fnp->fn_count = 0;
 889                 freemsg(bp);
 890         }
 891         fifo_wakewriter(fnp->fn_dest, fnp->fn_lock);
 892 }
 893 
 894 /*
 895  * Note:  This routine is single threaded
 896  *  Protected by FIFOOPEN flag (i.e. flk_lock is not held)
 897  *  Upon successful completion, the original fifo is unlocked
 898  *  and FIFOOPEN is cleared for the original vpp.
 899  *  The new fifo returned has FIFOOPEN set.
 900  */
 901 static int
 902 fifo_connld(struct vnode **vpp, int flag, cred_t *crp)
 903 {
 904         struct vnode *vp1;
 905         struct vnode *vp2;
 906         struct fifonode *oldfnp;
 907         struct fifonode *fn_dest;
 908         int error;
 909         struct file *filep;
 910         struct fifolock *fn_lock;
 911         cred_t *c;
 912 
 913         /*
 914          * Get two vnodes that will represent the pipe ends for the new pipe.
 915          */
 916         makepipe(&vp1, &vp2);
 917 
 918         /*
 919          * Allocate a file descriptor and file pointer for one of the pipe
 920          * ends. The file descriptor will be used to send that pipe end to
 921          * the process on the other end of this stream. Note that we get
 922          * the file structure only, there is no file list entry allocated.
 923          */
 924         if (error = falloc(vp1, FWRITE|FREAD, &filep, NULL)) {
 925                 VN_RELE(vp1);
 926                 VN_RELE(vp2);
 927                 return (error);
 928         }
 929         mutex_exit(&filep->f_tlock);
 930         oldfnp = VTOF(*vpp);
 931         fn_lock = oldfnp->fn_lock;
 932         fn_dest = oldfnp->fn_dest;
 933 
 934         /*
 935          * Create two new stream heads and attach them to the two vnodes for
 936          * the new pipe.
 937          */
 938         if ((error = fifo_stropen(&vp1, FREAD|FWRITE, filep->f_cred, 0, 0)) !=
 939             0 ||
 940             (error = fifo_stropen(&vp2, flag, filep->f_cred, 0, 0)) != 0) {
 941 #if DEBUG
 942                 cmn_err(CE_NOTE, "fifo stropen failed error 0x%x", error);
 943 #endif
 944                 /*
 945                  * this will call fifo_close and VN_RELE on vp1
 946                  */
 947                 (void) closef(filep);
 948                 VN_RELE(vp2);
 949                 return (error);
 950         }
 951 
 952         /*
 953          * twist the ends of the pipe together
 954          */
 955         strmate(vp1, vp2);
 956 
 957         /*
 958          * Set our end to busy in open
 959          * Note: Don't need lock around this because we're the only
 960          * one who knows about it
 961          */
 962         VTOF(vp2)->fn_flag |= FIFOOPEN;
 963 
 964         mutex_enter(&fn_lock->flk_lock);
 965 
 966         fn_dest->fn_flag |= FIFOSEND;
 967         /*
 968          * check to make sure neither end of pipe has gone away
 969          */
 970         if (!(fn_dest->fn_flag & FIFOISOPEN)) {
 971                 error = ENXIO;
 972                 fn_dest->fn_flag &= ~FIFOSEND;
 973                 mutex_exit(&fn_lock->flk_lock);
 974                 /*
 975                  * this will call fifo_close and VN_RELE on vp1
 976                  */
 977                 goto out;
 978         }
 979         mutex_exit(&fn_lock->flk_lock);
 980 
 981         /*
 982          * Tag the sender's credential on the pipe descriptor.
 983          */
 984         crhold(VTOF(vp1)->fn_pcredp = crp);
 985         VTOF(vp1)->fn_cpid = curproc->p_pid;
 986 
 987         /*
 988          * send the file descriptor to other end of pipe
 989          */
 990         if (error = do_sendfp((*vpp)->v_stream, filep, crp)) {
 991                 mutex_enter(&fn_lock->flk_lock);
 992                 fn_dest->fn_flag &= ~FIFOSEND;
 993                 mutex_exit(&fn_lock->flk_lock);
 994                 /*
 995                  * this will call fifo_close and VN_RELE on vp1
 996                  */
 997                 goto out;
 998         }
 999 
1000         mutex_enter(&fn_lock->flk_lock);
1001         /*
1002          * Wait for other end to receive file descriptor
1003          * FIFOCLOSE indicates that one or both sides of the pipe
1004          * have gone away.
1005          */
1006         while ((fn_dest->fn_flag & (FIFOCLOSE | FIFOSEND)) == FIFOSEND) {
1007                 if (!cv_wait_sig(&oldfnp->fn_wait_cv, &fn_lock->flk_lock)) {
1008                         error = EINTR;
1009                         fn_dest->fn_flag &= ~FIFOSEND;
1010                         mutex_exit(&fn_lock->flk_lock);
1011                         goto out;
1012                 }
1013         }
1014         /*
1015          * If either end of pipe has gone away and the other end did not
1016          * receive pipe, reject the connld open
1017          */
1018         if ((fn_dest->fn_flag & FIFOSEND)) {
1019                 error = ENXIO;
1020                 fn_dest->fn_flag &= ~FIFOSEND;
1021                 mutex_exit(&fn_lock->flk_lock);
1022                 goto out;
1023         }
1024 
1025         oldfnp->fn_flag &= ~FIFOOPEN;
1026         cv_broadcast(&oldfnp->fn_wait_cv);
1027         mutex_exit(&fn_lock->flk_lock);
1028 
1029         VN_RELE(*vpp);
1030         *vpp = vp2;
1031         (void) closef(filep);
1032         return (0);
1033 out:
1034         c = filep->f_cred;
1035         crhold(c);
1036         (void) closef(filep);
1037         VTOF(vp2)->fn_flag &= ~FIFOOPEN;
1038         (void) fifo_close(vp2, flag, 1, (offset_t)0, c, NULL);
1039         crfree(c);
1040         VN_RELE(vp2);
1041         return (error);
1042 }
1043 
1044 /*
1045  * Disable fastpath mode.
1046  */
1047 void
1048 fifo_fastoff(fifonode_t *fnp)
1049 {
1050         ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock));
1051         ASSERT(FTOV(fnp)->v_stream);
1052 
1053         /* FIFOSTAYFAST is set => FIFOFAST is set */
1054         while ((fnp->fn_flag & FIFOSTAYFAST) || ((fnp->fn_flag & ISPIPE) &&
1055             (fnp->fn_dest->fn_flag & FIFOSTAYFAST))) {
1056                 ASSERT(fnp->fn_flag & FIFOFAST);
1057                 /* indicate someone is waiting to turn into stream mode */
1058                 fnp->fn_flag |= FIFOWAITMODE;
1059                 cv_wait(&fnp->fn_wait_cv, &fnp->fn_lock->flk_lock);
1060                 fnp->fn_flag &= ~FIFOWAITMODE;
1061         }
1062 
1063         /* as we may have relased the lock, test the FIFOFAST flag here */
1064         if (!(fnp->fn_flag & FIFOFAST))
1065                 return;
1066 #if FIFODEBUG
1067         if (Fifo_verbose)
1068                 cmn_err(CE_NOTE, "Fifo reverting to streams mode\n");
1069 #endif
1070 
1071         fifo_fastturnoff(fnp);
1072         if (fnp->fn_flag & ISPIPE) {
1073                 fifo_fastturnoff(fnp->fn_dest);
1074         }
1075 }
1076 
1077 
1078 /*
1079  * flk_lock must be held while calling fifo_fastturnoff() to
1080  * preserve data ordering (no reads or writes allowed)
1081  */
1082 
1083 static void
1084 fifo_fastturnoff(fifonode_t *fnp)
1085 {
1086         fifonode_t *fn_dest = fnp->fn_dest;
1087         mblk_t  *fn_mp;
1088         int     fn_flag;
1089 
1090         ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock));
1091         /*
1092          * Note: This end can't be closed if there
1093          * is stuff in fn_mp
1094          */
1095         if ((fn_mp = fnp->fn_mp) != NULL) {
1096                 ASSERT(fnp->fn_flag & FIFOISOPEN);
1097                 ASSERT(FTOV(fnp)->v_stream != NULL);
1098                 ASSERT(FTOV(fnp)->v_stream->sd_wrq != NULL);
1099                 ASSERT(RD(FTOV(fnp)->v_stream->sd_wrq) != NULL);
1100                 ASSERT(strvp2wq(FTOV(fnp)) != NULL);
1101                 fnp->fn_mp = NULL;
1102                 fnp->fn_count = 0;
1103                 /*
1104                  * Don't need to drop flk_lock across the put()
1105                  * since we're just moving the message from the fifo
1106                  * node to the STREAM head...
1107                  */
1108                 put(RD(strvp2wq(FTOV(fnp))), fn_mp);
1109         }
1110 
1111         /*
1112          * Need to re-issue any pending poll requests
1113          * so that the STREAMS framework sees them
1114          * Writers would be waiting on fnp and readers on fn_dest
1115          */
1116         if ((fnp->fn_flag & (FIFOISOPEN | FIFOPOLLW)) ==
1117             (FIFOISOPEN | FIFOPOLLW)) {
1118                 strpollwakeup(FTOV(fnp), POLLWRNORM);
1119         }
1120         fn_flag = fn_dest->fn_flag;
1121         if ((fn_flag & FIFOISOPEN) == FIFOISOPEN) {
1122                 if ((fn_flag & (FIFOPOLLR | FIFOPOLLRBAND))) {
1123                         strpollwakeup(FTOV(fn_dest), POLLIN|POLLRDNORM);
1124                 }
1125         }
1126         /*
1127          * wake up any sleeping processes so they can notice we went
1128          * to streams mode
1129          */
1130         fnp->fn_flag &= ~(FIFOFAST|FIFOWANTW|FIFOWANTR);
1131         cv_broadcast(&fnp->fn_wait_cv);
1132 }
1133 
1134 /*
1135  * Alternative version of fifo_fastoff()
1136  * optimized for putmsg/getmsg.
1137  */
1138 void
1139 fifo_vfastoff(vnode_t *vp)
1140 {
1141         fifonode_t      *fnp = VTOF(vp);
1142 
1143         mutex_enter(&fnp->fn_lock->flk_lock);
1144         if (!(fnp->fn_flag & FIFOFAST)) {
1145                 mutex_exit(&fnp->fn_lock->flk_lock);
1146                 return;
1147         }
1148         fifo_fastoff(fnp);
1149         mutex_exit(&fnp->fn_lock->flk_lock);
1150 }
1151 
1152 /*
1153  * Wake any sleeping writers, poll and send signals if necessary
1154  * This module is only called when we drop below the hi water mark
1155  * FIFOWANTW indicates that a process is sleeping in fifo_write()
1156  * FIFOHIWATW indicates that we have either attempted a poll or
1157  * non-blocking write and were over the high water mark
1158  * This routine assumes a low water mark of 0.
1159  */
1160 
1161 void
1162 fifo_wakewriter(fifonode_t *fn_dest, fifolock_t *fn_lock)
1163 {
1164         int fn_dflag = fn_dest->fn_flag;
1165 
1166         ASSERT(MUTEX_HELD(&fn_lock->flk_lock));
1167         ASSERT(fn_dest->fn_dest->fn_count < Fifohiwat);
1168         if ((fn_dflag & FIFOWANTW)) {
1169                 cv_broadcast(&fn_dest->fn_wait_cv);
1170         }
1171         if ((fn_dflag & (FIFOHIWATW | FIFOISOPEN)) ==
1172             (FIFOHIWATW | FIFOISOPEN)) {
1173                 if (fn_dflag & FIFOPOLLW)
1174                         strpollwakeup(FTOV(fn_dest), POLLWRNORM);
1175                 if (fn_dflag & FIFOSETSIG)
1176                         str_sendsig(FTOV(fn_dest), S_WRNORM, 0, 0);
1177         }
1178         /*
1179          * FIFOPOLLW can't be set without setting FIFOHIWAT
1180          * This allows us to clear both here.
1181          */
1182         fn_dest->fn_flag = fn_dflag & ~(FIFOWANTW | FIFOHIWATW | FIFOPOLLW);
1183 }
1184 
1185 /*
1186  * wake up any sleeping readers, poll or send signal if needed
1187  * FIFOWANTR indicates that a process is waiting in fifo_read() for data
1188  * FIFOSETSIG indicates that SIGPOLL should be sent to process
1189  * FIFOPOLLR indicates that a poll request for reading on the fifo was made
1190  */
1191 
1192 void
1193 fifo_wakereader(fifonode_t *fn_dest, fifolock_t *fn_lock)
1194 {
1195         int fn_dflag = fn_dest->fn_flag;
1196 
1197         ASSERT(MUTEX_HELD(&fn_lock->flk_lock));
1198         if (fn_dflag & FIFOWANTR) {
1199                 cv_broadcast(&fn_dest->fn_wait_cv);
1200         }
1201         if (fn_dflag & FIFOISOPEN) {
1202                 if (fn_dflag & FIFOPOLLR)
1203                         strpollwakeup(FTOV(fn_dest), POLLIN | POLLRDNORM);
1204                 if (fn_dflag & FIFOSETSIG)
1205                         str_sendsig(FTOV(fn_dest), S_INPUT | S_RDNORM, 0, 0);
1206         }
1207         fn_dest->fn_flag = fn_dflag & ~(FIFOWANTR | FIFOPOLLR);
1208 }