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 inline int 1130 fifo_ioctl_getpeercred(fifonode_t *fnp, intptr_t arg, int mode) 1131 { 1132 k_peercred_t *kp = (k_peercred_t *)arg; 1133 1134 if (mode == FKIOCTL && fnp->fn_pcredp != NULL) { 1135 crhold(fnp->fn_pcredp); 1136 kp->pc_cr = fnp->fn_pcredp; 1137 kp->pc_cpid = fnp->fn_cpid; 1138 return (0); 1139 } else { 1140 return (ENOTSUP); 1141 } 1142 } 1143 1144 static int 1145 fifo_fastioctl(vnode_t *vp, int cmd, intptr_t arg, int mode, 1146 cred_t *cr, int *rvalp) 1147 { 1148 fifonode_t *fnp = VTOF(vp); 1149 fifonode_t *fn_dest; 1150 int error = 0; 1151 fifolock_t *fn_lock = fnp->fn_lock; 1152 int cnt; 1153 1154 /* 1155 * tty operations not allowed 1156 */ 1157 if (((cmd & IOCTYPE) == LDIOC) || 1158 ((cmd & IOCTYPE) == tIOC) || 1159 ((cmd & IOCTYPE) == TIOC)) { 1160 return (EINVAL); 1161 } 1162 1163 mutex_enter(&fn_lock->flk_lock); 1164 1165 if (!(fnp->fn_flag & FIFOFAST)) { 1166 goto stream_mode; 1167 } 1168 1169 switch (cmd) { 1170 1171 /* 1172 * Things we can't handle 1173 * These will switch us to streams mode. 1174 */ 1175 default: 1176 case I_STR: 1177 case I_SRDOPT: 1178 case I_PUSH: 1179 case I_FDINSERT: 1180 case I_SENDFD: 1181 case I_RECVFD: 1182 case I_E_RECVFD: 1183 case I_ATMARK: 1184 case I_CKBAND: 1185 case I_GETBAND: 1186 case I_SWROPT: 1187 goto turn_fastoff; 1188 1189 /* 1190 * Things that don't do damage 1191 * These things don't adjust the state of the 1192 * stream head (i_setcltime does, but we don't care) 1193 */ 1194 case I_FIND: 1195 case I_GETSIG: 1196 case FIONBIO: 1197 case FIOASYNC: 1198 case I_GRDOPT: /* probably should not get this, but no harm */ 1199 case I_GWROPT: 1200 case I_LIST: 1201 case I_SETCLTIME: 1202 case I_GETCLTIME: 1203 mutex_exit(&fn_lock->flk_lock); 1204 return (strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp)); 1205 1206 case I_CANPUT: 1207 /* 1208 * We can only handle normal band canputs. 1209 * XXX : We could just always go to stream mode; after all 1210 * canput is a streams semantics type thing 1211 */ 1212 if (arg != 0) { 1213 goto turn_fastoff; 1214 } 1215 *rvalp = (fnp->fn_dest->fn_count < Fifohiwat) ? 1 : 0; 1216 mutex_exit(&fn_lock->flk_lock); 1217 return (0); 1218 1219 case I_NREAD: 1220 /* 1221 * This may seem a bit silly for non-streams semantics, 1222 * (After all, if they really want a message, they'll 1223 * probably use getmsg() anyway). but it doesn't hurt 1224 */ 1225 error = copyout((caddr_t)&fnp->fn_count, (caddr_t)arg, 1226 sizeof (cnt)); 1227 if (error == 0) { 1228 *rvalp = (fnp->fn_count == 0) ? 0 : 1; 1229 } 1230 break; 1231 1232 case FIORDCHK: 1233 *rvalp = fnp->fn_count; 1234 break; 1235 1236 case I_PEEK: 1237 { 1238 STRUCT_DECL(strpeek, strpeek); 1239 struct uio uio; 1240 struct iovec iov; 1241 int count; 1242 mblk_t *bp; 1243 int len; 1244 1245 STRUCT_INIT(strpeek, mode); 1246 1247 if (fnp->fn_count == 0) { 1248 *rvalp = 0; 1249 break; 1250 } 1251 1252 error = copyin((caddr_t)arg, STRUCT_BUF(strpeek), 1253 STRUCT_SIZE(strpeek)); 1254 if (error) 1255 break; 1256 1257 /* 1258 * can't have any high priority message when in fast mode 1259 */ 1260 if (STRUCT_FGET(strpeek, flags) & RS_HIPRI) { 1261 *rvalp = 0; 1262 break; 1263 } 1264 1265 len = STRUCT_FGET(strpeek, databuf.maxlen); 1266 if (len <= 0) { 1267 STRUCT_FSET(strpeek, databuf.len, len); 1268 } else { 1269 iov.iov_base = STRUCT_FGETP(strpeek, databuf.buf); 1270 iov.iov_len = len; 1271 uio.uio_iov = &iov; 1272 uio.uio_iovcnt = 1; 1273 uio.uio_loffset = 0; 1274 uio.uio_segflg = UIO_USERSPACE; 1275 uio.uio_fmode = 0; 1276 /* For pipes copy should not bypass cache */ 1277 uio.uio_extflg = UIO_COPY_CACHED; 1278 uio.uio_resid = iov.iov_len; 1279 count = fnp->fn_count; 1280 bp = fnp->fn_mp; 1281 while (count > 0 && uio.uio_resid) { 1282 cnt = MIN(uio.uio_resid, MBLKL(bp)); 1283 if ((error = uiomove((char *)bp->b_rptr, cnt, 1284 UIO_READ, &uio)) != 0) { 1285 break; 1286 } 1287 count -= cnt; 1288 bp = bp->b_cont; 1289 } 1290 STRUCT_FSET(strpeek, databuf.len, len - uio.uio_resid); 1291 } 1292 STRUCT_FSET(strpeek, flags, 0); 1293 STRUCT_FSET(strpeek, ctlbuf.len, -1); 1294 1295 error = copyout(STRUCT_BUF(strpeek), (caddr_t)arg, 1296 STRUCT_SIZE(strpeek)); 1297 if (error == 0 && len >= 0) 1298 *rvalp = 1; 1299 break; 1300 } 1301 1302 case FIONREAD: 1303 /* 1304 * let user know total number of bytes in message queue 1305 */ 1306 error = copyout((caddr_t)&fnp->fn_count, (caddr_t)arg, 1307 sizeof (fnp->fn_count)); 1308 if (error == 0) 1309 *rvalp = 0; 1310 break; 1311 1312 case I_SETSIG: 1313 /* 1314 * let streams set up the signal masking for us 1315 * we just check to see if it's set 1316 * XXX : this interface should not be visible 1317 * i.e. STREAM's framework is exposed. 1318 */ 1319 error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp); 1320 if (vp->v_stream->sd_sigflags & (S_INPUT|S_RDNORM|S_WRNORM)) 1321 fnp->fn_flag |= FIFOSETSIG; 1322 else 1323 fnp->fn_flag &= ~FIFOSETSIG; 1324 break; 1325 1326 case I_FLUSH: 1327 /* 1328 * flush them message queues 1329 */ 1330 if (arg & ~FLUSHRW) { 1331 error = EINVAL; 1332 break; 1333 } 1334 if (arg & FLUSHR) { 1335 fifo_fastflush(fnp); 1336 } 1337 fn_dest = fnp->fn_dest; 1338 if ((arg & FLUSHW)) { 1339 fifo_fastflush(fn_dest); 1340 } 1341 /* 1342 * wake up any sleeping readers or writers 1343 * (waking readers probably doesn't make sense, but it 1344 * doesn't hurt; i.e. we just got rid of all the data 1345 * what's to read ?) 1346 */ 1347 if (fn_dest->fn_flag & (FIFOWANTW | FIFOWANTR)) { 1348 fn_dest->fn_flag &= ~(FIFOWANTW | FIFOWANTR); 1349 cv_broadcast(&fn_dest->fn_wait_cv); 1350 } 1351 *rvalp = 0; 1352 break; 1353 1354 /* 1355 * Since no band data can ever get on a fifo in fast mode 1356 * just return 0. 1357 */ 1358 case I_FLUSHBAND: 1359 error = 0; 1360 *rvalp = 0; 1361 break; 1362 1363 case _I_GETPEERCRED: 1364 error = fifo_ioctl_getpeercred(fnp, arg, mode); 1365 break; 1366 1367 /* 1368 * invalid calls for stream head or fifos 1369 */ 1370 1371 case I_POP: /* shouldn't happen */ 1372 case I_LOOK: 1373 case I_LINK: 1374 case I_PLINK: 1375 case I_UNLINK: 1376 case I_PUNLINK: 1377 1378 /* 1379 * more invalid tty type of ioctls 1380 */ 1381 1382 case SRIOCSREDIR: 1383 case SRIOCISREDIR: 1384 error = EINVAL; 1385 break; 1386 1387 } 1388 mutex_exit(&fn_lock->flk_lock); 1389 return (error); 1390 1391 turn_fastoff: 1392 fifo_fastoff(fnp); 1393 1394 stream_mode: 1395 /* 1396 * streams mode 1397 */ 1398 mutex_exit(&fn_lock->flk_lock); 1399 return (fifo_strioctl(vp, cmd, arg, mode, cr, rvalp)); 1400 1401 } 1402 1403 /* 1404 * FIFO is in STREAMS mode; STREAMS framework does most of the work. 1405 */ 1406 static int 1407 fifo_strioctl(vnode_t *vp, int cmd, intptr_t arg, int mode, 1408 cred_t *cr, int *rvalp) 1409 { 1410 fifonode_t *fnp = VTOF(vp); 1411 int error; 1412 fifolock_t *fn_lock; 1413 1414 if (cmd == _I_GETPEERCRED) 1415 return (fifo_ioctl_getpeercred(fnp, arg, mode)); 1416 1417 error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp); 1418 1419 switch (cmd) { 1420 /* 1421 * The FIFOSEND flag is set to inform other processes that a file 1422 * descriptor is pending at the stream head of this pipe. 1423 * The flag is cleared and the sending process is awoken when 1424 * this process has completed receiving the file descriptor. 1425 * XXX This could become out of sync if the process does I_SENDFDs 1426 * and opens on connld attached to the same pipe. 1427 */ 1428 case I_RECVFD: 1429 case I_E_RECVFD: 1430 if (error == 0) { 1431 fn_lock = fnp->fn_lock; 1432 mutex_enter(&fn_lock->flk_lock); 1433 if (fnp->fn_flag & FIFOSEND) { 1434 fnp->fn_flag &= ~FIFOSEND; 1435 cv_broadcast(&fnp->fn_dest->fn_wait_cv); 1436 } 1437 mutex_exit(&fn_lock->flk_lock); 1438 } 1439 break; 1440 default: 1441 break; 1442 } 1443 1444 return (error); 1445 } 1446 1447 /* 1448 * If shadowing a vnode (FIFOs), apply the VOP_GETATTR to the shadowed 1449 * vnode to Obtain the node information. If not shadowing (pipes), obtain 1450 * the node information from the credentials structure. 1451 */ 1452 int 1453 fifo_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *crp, 1454 caller_context_t *ct) 1455 { 1456 int error = 0; 1457 fifonode_t *fnp = VTOF(vp); 1458 queue_t *qp; 1459 qband_t *bandp; 1460 fifolock_t *fn_lock = fnp->fn_lock; 1461 1462 if (fnp->fn_realvp) { 1463 /* 1464 * for FIFOs or mounted pipes 1465 */ 1466 if (error = VOP_GETATTR(fnp->fn_realvp, vap, flags, crp, ct)) 1467 return (error); 1468 mutex_enter(&fn_lock->flk_lock); 1469 /* set current times from fnode, even if older than vnode */ 1470 vap->va_atime.tv_sec = fnp->fn_atime; 1471 vap->va_atime.tv_nsec = 0; 1472 vap->va_mtime.tv_sec = fnp->fn_mtime; 1473 vap->va_mtime.tv_nsec = 0; 1474 vap->va_ctime.tv_sec = fnp->fn_ctime; 1475 vap->va_ctime.tv_nsec = 0; 1476 } else { 1477 /* 1478 * for non-attached/ordinary pipes 1479 */ 1480 vap->va_mode = 0; 1481 mutex_enter(&fn_lock->flk_lock); 1482 vap->va_atime.tv_sec = fnp->fn_atime; 1483 vap->va_atime.tv_nsec = 0; 1484 vap->va_mtime.tv_sec = fnp->fn_mtime; 1485 vap->va_mtime.tv_nsec = 0; 1486 vap->va_ctime.tv_sec = fnp->fn_ctime; 1487 vap->va_ctime.tv_nsec = 0; 1488 vap->va_uid = crgetuid(crp); 1489 vap->va_gid = crgetgid(crp); 1490 vap->va_nlink = 0; 1491 vap->va_fsid = fifodev; 1492 vap->va_nodeid = (ino64_t)fnp->fn_ino; 1493 vap->va_rdev = 0; 1494 } 1495 vap->va_type = VFIFO; 1496 vap->va_blksize = PIPE_BUF; 1497 /* 1498 * Size is number of un-read bytes at the stream head and 1499 * nblocks is the unread bytes expressed in blocks. 1500 */ 1501 if (vp->v_stream && (fnp->fn_flag & FIFOISOPEN)) { 1502 if ((fnp->fn_flag & FIFOFAST)) { 1503 vap->va_size = (u_offset_t)fnp->fn_count; 1504 } else { 1505 qp = RD((strvp2wq(vp))); 1506 vap->va_size = (u_offset_t)qp->q_count; 1507 if (qp->q_nband != 0) { 1508 mutex_enter(QLOCK(qp)); 1509 for (bandp = qp->q_bandp; bandp; 1510 bandp = bandp->qb_next) 1511 vap->va_size += bandp->qb_count; 1512 mutex_exit(QLOCK(qp)); 1513 } 1514 } 1515 vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size); 1516 } else { 1517 vap->va_size = (u_offset_t)0; 1518 vap->va_nblocks = (fsblkcnt64_t)0; 1519 } 1520 mutex_exit(&fn_lock->flk_lock); 1521 vap->va_seq = 0; 1522 return (0); 1523 } 1524 1525 /* 1526 * If shadowing a vnode, apply the VOP_SETATTR to it, and to the fnode. 1527 * Otherwise, set the time and return 0. 1528 */ 1529 int 1530 fifo_setattr( 1531 vnode_t *vp, 1532 vattr_t *vap, 1533 int flags, 1534 cred_t *crp, 1535 caller_context_t *ctp) 1536 { 1537 fifonode_t *fnp = VTOF(vp); 1538 int error = 0; 1539 fifolock_t *fn_lock; 1540 1541 if (fnp->fn_realvp) 1542 error = VOP_SETATTR(fnp->fn_realvp, vap, flags, crp, ctp); 1543 if (error == 0) { 1544 fn_lock = fnp->fn_lock; 1545 mutex_enter(&fn_lock->flk_lock); 1546 if (vap->va_mask & AT_ATIME) 1547 fnp->fn_atime = vap->va_atime.tv_sec; 1548 if (vap->va_mask & AT_MTIME) 1549 fnp->fn_mtime = vap->va_mtime.tv_sec; 1550 fnp->fn_ctime = gethrestime_sec(); 1551 mutex_exit(&fn_lock->flk_lock); 1552 } 1553 return (error); 1554 } 1555 1556 /* 1557 * If shadowing a vnode, apply VOP_ACCESS to it. 1558 * Otherwise, return 0 (allow all access). 1559 */ 1560 int 1561 fifo_access(vnode_t *vp, int mode, int flags, cred_t *crp, caller_context_t *ct) 1562 { 1563 if (VTOF(vp)->fn_realvp) 1564 return (VOP_ACCESS(VTOF(vp)->fn_realvp, mode, flags, crp, ct)); 1565 else 1566 return (0); 1567 } 1568 1569 /* 1570 * This can be called if creat or an open with O_CREAT is done on the root 1571 * of a lofs mount where the mounted entity is a fifo. 1572 */ 1573 /*ARGSUSED*/ 1574 static int 1575 fifo_create(struct vnode *dvp, char *name, vattr_t *vap, enum vcexcl excl, 1576 int mode, struct vnode **vpp, struct cred *cr, int flag, 1577 caller_context_t *ct, vsecattr_t *vsecp) 1578 { 1579 int error; 1580 1581 ASSERT(dvp && (dvp->v_flag & VROOT) && *name == '\0'); 1582 if (excl == NONEXCL) { 1583 if (mode && (error = fifo_access(dvp, mode, 0, cr, ct))) 1584 return (error); 1585 VN_HOLD(dvp); 1586 return (0); 1587 } 1588 return (EEXIST); 1589 } 1590 1591 /* 1592 * If shadowing a vnode, apply the VOP_FSYNC to it. 1593 * Otherwise, return 0. 1594 */ 1595 int 1596 fifo_fsync(vnode_t *vp, int syncflag, cred_t *crp, caller_context_t *ct) 1597 { 1598 fifonode_t *fnp = VTOF(vp); 1599 vattr_t va; 1600 1601 if (fnp->fn_realvp == NULL) 1602 return (0); 1603 1604 bzero((caddr_t)&va, sizeof (va)); 1605 va.va_mask = AT_MTIME | AT_ATIME; 1606 if (VOP_GETATTR(fnp->fn_realvp, &va, 0, crp, ct) == 0) { 1607 va.va_mask = 0; 1608 if (fnp->fn_mtime > va.va_mtime.tv_sec) { 1609 va.va_mtime.tv_sec = fnp->fn_mtime; 1610 va.va_mask = AT_MTIME; 1611 } 1612 if (fnp->fn_atime > va.va_atime.tv_sec) { 1613 va.va_atime.tv_sec = fnp->fn_atime; 1614 va.va_mask |= AT_ATIME; 1615 } 1616 if (va.va_mask != 0) 1617 (void) VOP_SETATTR(fnp->fn_realvp, &va, 0, crp, ct); 1618 } 1619 return (VOP_FSYNC(fnp->fn_realvp, syncflag, crp, ct)); 1620 } 1621 1622 /* 1623 * Called when the upper level no longer holds references to the 1624 * vnode. Sync the file system and free the fifonode. 1625 */ 1626 void 1627 fifo_inactive(vnode_t *vp, cred_t *crp, caller_context_t *ct) 1628 { 1629 fifonode_t *fnp; 1630 fifolock_t *fn_lock; 1631 1632 mutex_enter(&ftable_lock); 1633 mutex_enter(&vp->v_lock); 1634 ASSERT(vp->v_count >= 1); 1635 if (--vp->v_count != 0) { 1636 /* 1637 * Somebody accessed the fifo before we got a chance to 1638 * remove it. They will remove it when they do a vn_rele. 1639 */ 1640 mutex_exit(&vp->v_lock); 1641 mutex_exit(&ftable_lock); 1642 return; 1643 } 1644 mutex_exit(&vp->v_lock); 1645 1646 fnp = VTOF(vp); 1647 1648 /* 1649 * remove fifo from fifo list so that no other process 1650 * can grab it. 1651 * Drop the reference count on the fifo node's 1652 * underlying vfs. 1653 */ 1654 if (fnp->fn_realvp) { 1655 (void) fiforemove(fnp); 1656 mutex_exit(&ftable_lock); 1657 (void) fifo_fsync(vp, FSYNC, crp, ct); 1658 VN_RELE(fnp->fn_realvp); 1659 VFS_RELE(vp->v_vfsp); 1660 vp->v_vfsp = NULL; 1661 } else 1662 mutex_exit(&ftable_lock); 1663 1664 fn_lock = fnp->fn_lock; 1665 1666 mutex_enter(&fn_lock->flk_lock); 1667 ASSERT(vp->v_stream == NULL); 1668 ASSERT(vp->v_count == 0); 1669 /* 1670 * if this is last reference to the lock, then we can 1671 * free everything up. 1672 */ 1673 if (--fn_lock->flk_ref == 0) { 1674 mutex_exit(&fn_lock->flk_lock); 1675 ASSERT(fnp->fn_open == 0); 1676 ASSERT(fnp->fn_dest->fn_open == 0); 1677 if (fnp->fn_mp) { 1678 freemsg(fnp->fn_mp); 1679 fnp->fn_mp = NULL; 1680 fnp->fn_count = 0; 1681 } 1682 if (fnp->fn_pcredp != NULL) { 1683 crfree(fnp->fn_pcredp); 1684 fnp->fn_pcredp = NULL; 1685 } 1686 if (fnp->fn_flag & ISPIPE) { 1687 fifonode_t *fn_dest = fnp->fn_dest; 1688 1689 vp = FTOV(fn_dest); 1690 if (fn_dest->fn_mp) { 1691 freemsg(fn_dest->fn_mp); 1692 fn_dest->fn_mp = NULL; 1693 fn_dest->fn_count = 0; 1694 } 1695 if (fn_dest->fn_pcredp != NULL) { 1696 crfree(fn_dest->fn_pcredp); 1697 fn_dest->fn_pcredp = NULL; 1698 } 1699 kmem_cache_free(pipe_cache, (fifodata_t *)fn_lock); 1700 } else 1701 kmem_cache_free(fnode_cache, (fifodata_t *)fn_lock); 1702 } else { 1703 mutex_exit(&fn_lock->flk_lock); 1704 } 1705 } 1706 1707 /* 1708 * If shadowing a vnode, apply the VOP_FID to it. 1709 * Otherwise, return EINVAL. 1710 */ 1711 int 1712 fifo_fid(vnode_t *vp, fid_t *fidfnp, caller_context_t *ct) 1713 { 1714 if (VTOF(vp)->fn_realvp) 1715 return (VOP_FID(VTOF(vp)->fn_realvp, fidfnp, ct)); 1716 else 1717 return (EINVAL); 1718 } 1719 1720 /* 1721 * Lock a fifonode. 1722 */ 1723 /* ARGSUSED */ 1724 int 1725 fifo_rwlock(vnode_t *vp, int write_lock, caller_context_t *ctp) 1726 { 1727 return (-1); 1728 } 1729 1730 /* 1731 * Unlock a fifonode. 1732 */ 1733 /* ARGSUSED */ 1734 void 1735 fifo_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ctp) 1736 { 1737 } 1738 1739 /* 1740 * Return error since seeks are not allowed on pipes. 1741 */ 1742 /*ARGSUSED*/ 1743 int 1744 fifo_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct) 1745 { 1746 return (ESPIPE); 1747 } 1748 1749 /* 1750 * If there is a realvp associated with vp, return it. 1751 */ 1752 int 1753 fifo_realvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct) 1754 { 1755 vnode_t *rvp; 1756 1757 if ((rvp = VTOF(vp)->fn_realvp) != NULL) { 1758 vp = rvp; 1759 if (VOP_REALVP(vp, &rvp, ct) == 0) 1760 vp = rvp; 1761 } 1762 1763 *vpp = vp; 1764 return (0); 1765 } 1766 1767 /* 1768 * Poll for interesting events on a stream pipe 1769 */ 1770 /* ARGSUSED */ 1771 int 1772 fifo_poll(vnode_t *vp, short events, int anyyet, short *reventsp, 1773 pollhead_t **phpp, caller_context_t *ct) 1774 { 1775 fifonode_t *fnp, *fn_dest; 1776 fifolock_t *fn_lock; 1777 int retevents; 1778 struct stdata *stp; 1779 1780 ASSERT(vp->v_stream != NULL); 1781 1782 stp = vp->v_stream; 1783 retevents = 0; 1784 fnp = VTOF(vp); 1785 fn_dest = fnp->fn_dest; 1786 fn_lock = fnp->fn_lock; 1787 1788 if (polllock(&stp->sd_pollist, &fn_lock->flk_lock) != 0) { 1789 *reventsp = POLLNVAL; 1790 return (0); 1791 } 1792 1793 /* 1794 * see if FIFO/pipe open 1795 */ 1796 if ((fnp->fn_flag & FIFOISOPEN) == 0) { 1797 if (((events & (POLLIN | POLLRDNORM | POLLPRI | POLLRDBAND)) && 1798 fnp->fn_rcnt == 0) || 1799 ((events & (POLLWRNORM | POLLWRBAND)) && 1800 fnp->fn_wcnt == 0)) { 1801 mutex_exit(&fnp->fn_lock->flk_lock); 1802 *reventsp = POLLERR; 1803 return (0); 1804 } 1805 } 1806 1807 /* 1808 * if not in fast mode, let the stream head take care of it 1809 */ 1810 if (!(fnp->fn_flag & FIFOFAST)) { 1811 mutex_exit(&fnp->fn_lock->flk_lock); 1812 goto stream_mode; 1813 } 1814 1815 /* 1816 * If this is a pipe.. check to see if the other 1817 * end is gone. If we are a fifo, check to see 1818 * if write end is gone. 1819 */ 1820 1821 if ((fnp->fn_flag & ISPIPE) && (fn_dest->fn_open == 0)) { 1822 retevents = POLLHUP; 1823 } else if ((fnp->fn_flag & (FIFOCLOSE | ISPIPE)) == FIFOCLOSE && 1824 (fn_dest->fn_wcnt == 0)) { 1825 /* 1826 * no writer at other end. 1827 * it was closed (versus yet to be opened) 1828 */ 1829 retevents = POLLHUP; 1830 } else if (events & (POLLWRNORM | POLLWRBAND)) { 1831 if (events & POLLWRNORM) { 1832 if (fn_dest->fn_count < Fifohiwat) 1833 retevents = POLLWRNORM; 1834 else 1835 fnp->fn_flag |= FIFOHIWATW; 1836 } 1837 /* 1838 * This is always true for fast pipes 1839 * (Note: will go to STREAMS mode if band data is written) 1840 */ 1841 if (events & POLLWRBAND) 1842 retevents |= POLLWRBAND; 1843 } 1844 if (events & (POLLIN | POLLRDNORM)) { 1845 if (fnp->fn_count) 1846 retevents |= (events & (POLLIN | POLLRDNORM)); 1847 } 1848 1849 /* 1850 * if we happened to get something and we're not edge-triggered, return 1851 */ 1852 if ((*reventsp = (short)retevents) != 0 && !(events & POLLET)) { 1853 mutex_exit(&fnp->fn_lock->flk_lock); 1854 return (0); 1855 } 1856 1857 /* 1858 * If poll() has not found any events yet or we're edge-triggered, set 1859 * up event cell to wake up the poll if a requested event occurs on this 1860 * pipe/fifo. 1861 */ 1862 if (!anyyet) { 1863 if (events & POLLWRNORM) 1864 fnp->fn_flag |= FIFOPOLLW; 1865 if (events & (POLLIN | POLLRDNORM)) 1866 fnp->fn_flag |= FIFOPOLLR; 1867 if (events & POLLRDBAND) 1868 fnp->fn_flag |= FIFOPOLLRBAND; 1869 /* 1870 * XXX Don't like exposing this from streams 1871 */ 1872 *phpp = &stp->sd_pollist; 1873 } 1874 mutex_exit(&fnp->fn_lock->flk_lock); 1875 return (0); 1876 stream_mode: 1877 return (strpoll(stp, events, anyyet, reventsp, phpp)); 1878 } 1879 1880 /* 1881 * POSIX pathconf() support. 1882 */ 1883 /* ARGSUSED */ 1884 int 1885 fifo_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, 1886 caller_context_t *ct) 1887 { 1888 ulong_t val; 1889 int error = 0; 1890 1891 switch (cmd) { 1892 1893 case _PC_LINK_MAX: 1894 val = MAXLINK; 1895 break; 1896 1897 case _PC_MAX_CANON: 1898 val = MAX_CANON; 1899 break; 1900 1901 case _PC_MAX_INPUT: 1902 val = MAX_INPUT; 1903 break; 1904 1905 case _PC_NAME_MAX: 1906 error = EINVAL; 1907 break; 1908 1909 case _PC_PATH_MAX: 1910 case _PC_SYMLINK_MAX: 1911 val = MAXPATHLEN; 1912 break; 1913 1914 case _PC_PIPE_BUF: 1915 val = PIPE_BUF; 1916 break; 1917 1918 case _PC_NO_TRUNC: 1919 if (vp->v_vfsp->vfs_flag & VFS_NOTRUNC) 1920 val = 1; /* NOTRUNC is enabled for vp */ 1921 else 1922 val = (ulong_t)-1; 1923 break; 1924 1925 case _PC_VDISABLE: 1926 val = _POSIX_VDISABLE; 1927 break; 1928 1929 case _PC_CHOWN_RESTRICTED: 1930 if (rstchown) 1931 val = rstchown; /* chown restricted enabled */ 1932 else 1933 val = (ulong_t)-1; 1934 break; 1935 1936 case _PC_FILESIZEBITS: 1937 val = (ulong_t)-1; 1938 break; 1939 1940 default: 1941 if (VTOF(vp)->fn_realvp) 1942 error = VOP_PATHCONF(VTOF(vp)->fn_realvp, cmd, 1943 &val, cr, ct); 1944 else 1945 error = EINVAL; 1946 break; 1947 } 1948 1949 if (error == 0) 1950 *valp = val; 1951 return (error); 1952 } 1953 1954 /* 1955 * If shadowing a vnode, apply VOP_SETSECATTR to it. 1956 * Otherwise, return NOSYS. 1957 */ 1958 int 1959 fifo_setsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *crp, 1960 caller_context_t *ct) 1961 { 1962 int error; 1963 1964 /* 1965 * The acl(2) system call tries to grab the write lock on the 1966 * file when setting an ACL, but fifofs does not implement 1967 * VOP_RWLOCK or VOP_RWUNLOCK, so we do it here instead. 1968 */ 1969 if (VTOF(vp)->fn_realvp) { 1970 (void) VOP_RWLOCK(VTOF(vp)->fn_realvp, V_WRITELOCK_TRUE, ct); 1971 error = VOP_SETSECATTR(VTOF(vp)->fn_realvp, vsap, flag, 1972 crp, ct); 1973 VOP_RWUNLOCK(VTOF(vp)->fn_realvp, V_WRITELOCK_TRUE, ct); 1974 return (error); 1975 } else 1976 return (fs_nosys()); 1977 } 1978 1979 /* 1980 * If shadowing a vnode, apply VOP_GETSECATTR to it. Otherwise, fabricate 1981 * an ACL from the permission bits that fifo_getattr() makes up. 1982 */ 1983 int 1984 fifo_getsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *crp, 1985 caller_context_t *ct) 1986 { 1987 if (VTOF(vp)->fn_realvp) 1988 return (VOP_GETSECATTR(VTOF(vp)->fn_realvp, vsap, flag, 1989 crp, ct)); 1990 else 1991 return (fs_fab_acl(vp, vsap, flag, crp, ct)); 1992 } 1993 1994 1995 /* 1996 * Set the FIFOSTAYFAST flag so nobody can turn the fifo into stream mode. 1997 * If the flag is already set then wait until it is removed - releasing 1998 * the lock. 1999 * If the fifo switches into stream mode while we are waiting, return failure. 2000 */ 2001 static boolean_t 2002 fifo_stayfast_enter(fifonode_t *fnp) 2003 { 2004 ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock)); 2005 while (fnp->fn_flag & FIFOSTAYFAST) { 2006 fnp->fn_flag |= FIFOWAITMODE; 2007 cv_wait(&fnp->fn_wait_cv, &fnp->fn_lock->flk_lock); 2008 fnp->fn_flag &= ~FIFOWAITMODE; 2009 } 2010 if (!(fnp->fn_flag & FIFOFAST)) 2011 return (B_FALSE); 2012 2013 fnp->fn_flag |= FIFOSTAYFAST; 2014 return (B_TRUE); 2015 } 2016 2017 /* 2018 * Unset the FIFOSTAYFAST flag and notify anybody waiting for this flag 2019 * to be removed: 2020 * - threads wanting to turn into stream mode waiting in fifo_fastoff(), 2021 * - other writers threads waiting in fifo_stayfast_enter(). 2022 */ 2023 static void 2024 fifo_stayfast_exit(fifonode_t *fnp) 2025 { 2026 fifonode_t *fn_dest = fnp->fn_dest; 2027 2028 ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock)); 2029 2030 fnp->fn_flag &= ~FIFOSTAYFAST; 2031 2032 if (fnp->fn_flag & FIFOWAITMODE) 2033 cv_broadcast(&fnp->fn_wait_cv); 2034 2035 if ((fnp->fn_flag & ISPIPE) && (fn_dest->fn_flag & FIFOWAITMODE)) 2036 cv_broadcast(&fn_dest->fn_wait_cv); 2037 }