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