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