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