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