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