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