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