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