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