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