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