kill tsol ("Trusted Solaris") aka TX ("Trusted Extensions")
[unleashed.git] / kernel / fs / fifofs / fifovnops.c
blob9cbfdb28b05d513910775cae8d6bd97b88b3eaf9
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 /* All rights reserved. */
26 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
31 * Copyright 2015, Joyent, Inc.
35 * FIFOFS file system vnode operations. This file system
36 * type supports STREAMS-based pipes and FIFOs.
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/sysmacros.h>
42 #include <sys/cred.h>
43 #include <sys/errno.h>
44 #include <sys/time.h>
45 #include <sys/file.h>
46 #include <sys/fcntl.h>
47 #include <sys/kmem.h>
48 #include <sys/uio.h>
49 #include <sys/vfs.h>
50 #include <sys/vnode.h>
51 #include <sys/vfs_opreg.h>
52 #include <sys/pathname.h>
53 #include <sys/signal.h>
54 #include <sys/user.h>
55 #include <sys/strsubr.h>
56 #include <sys/stream.h>
57 #include <sys/strsun.h>
58 #include <sys/strredir.h>
59 #include <sys/fs/fifonode.h>
60 #include <sys/fs/namenode.h>
61 #include <sys/stropts.h>
62 #include <sys/proc.h>
63 #include <sys/unistd.h>
64 #include <sys/debug.h>
65 #include <sys/fs_subr.h>
66 #include <sys/filio.h>
67 #include <sys/termio.h>
68 #include <sys/ddi.h>
69 #include <sys/vtrace.h>
70 #include <sys/policy.h>
73 * Define the routines/data structures used in this file.
75 static int fifo_read(vnode_t *, uio_t *, int, cred_t *, caller_context_t *);
76 static int fifo_write(vnode_t *, uio_t *, int, cred_t *, caller_context_t *);
77 static int fifo_getattr(vnode_t *, vattr_t *, int, cred_t *,
78 caller_context_t *);
79 static int fifo_setattr(vnode_t *, vattr_t *, int, cred_t *,
80 caller_context_t *);
81 static int fifo_realvp(vnode_t *, vnode_t **, caller_context_t *);
82 static int fifo_access(vnode_t *, int, int, cred_t *, caller_context_t *);
83 static int fifo_create(struct vnode *, char *, vattr_t *, enum vcexcl,
84 int, struct vnode **, struct cred *, int, caller_context_t *,
85 vsecattr_t *);
86 static int fifo_fid(vnode_t *, fid_t *, caller_context_t *);
87 static int fifo_fsync(vnode_t *, int, cred_t *, caller_context_t *);
88 static int fifo_seek(vnode_t *, offset_t, offset_t *, caller_context_t *);
89 static int fifo_ioctl(vnode_t *, int, intptr_t, int, cred_t *, int *,
90 caller_context_t *);
91 static int fifo_fastioctl(vnode_t *, int, intptr_t, int, cred_t *, int *);
92 static int fifo_strioctl(vnode_t *, int, intptr_t, int, cred_t *, int *);
93 static int fifo_poll(vnode_t *, short, int, short *, pollhead_t **,
94 caller_context_t *);
95 static int fifo_pathconf(vnode_t *, int, ulong_t *, cred_t *,
96 caller_context_t *);
97 static void fifo_inactive(vnode_t *, cred_t *, caller_context_t *);
98 static int fifo_rwlock(vnode_t *, int, caller_context_t *);
99 static void fifo_rwunlock(vnode_t *, int, caller_context_t *);
100 static int fifo_setsecattr(struct vnode *, vsecattr_t *, int, struct cred *,
101 caller_context_t *);
102 static int fifo_getsecattr(struct vnode *, vsecattr_t *, int, struct cred *,
103 caller_context_t *);
105 /* functions local to this file */
106 static boolean_t fifo_stayfast_enter(fifonode_t *);
107 static void fifo_stayfast_exit(fifonode_t *);
110 * Define the data structures external to this file.
112 extern dev_t fifodev;
113 extern struct qinit fifo_stwdata;
114 extern struct qinit fifo_strdata;
115 extern kmutex_t ftable_lock;
117 struct streamtab fifoinfo = { &fifo_strdata, &fifo_stwdata, NULL, NULL };
119 struct vnodeops *fifo_vnodeops;
121 const fs_operation_def_t fifo_vnodeops_template[] = {
122 VOPNAME_OPEN, { .vop_open = fifo_open },
123 VOPNAME_CLOSE, { .vop_close = fifo_close },
124 VOPNAME_READ, { .vop_read = fifo_read },
125 VOPNAME_WRITE, { .vop_write = fifo_write },
126 VOPNAME_IOCTL, { .vop_ioctl = fifo_ioctl },
127 VOPNAME_GETATTR, { .vop_getattr = fifo_getattr },
128 VOPNAME_SETATTR, { .vop_setattr = fifo_setattr },
129 VOPNAME_ACCESS, { .vop_access = fifo_access },
130 VOPNAME_CREATE, { .vop_create = fifo_create },
131 VOPNAME_FSYNC, { .vop_fsync = fifo_fsync },
132 VOPNAME_INACTIVE, { .vop_inactive = fifo_inactive },
133 VOPNAME_FID, { .vop_fid = fifo_fid },
134 VOPNAME_RWLOCK, { .vop_rwlock = fifo_rwlock },
135 VOPNAME_RWUNLOCK, { .vop_rwunlock = fifo_rwunlock },
136 VOPNAME_SEEK, { .vop_seek = fifo_seek },
137 VOPNAME_REALVP, { .vop_realvp = fifo_realvp },
138 VOPNAME_POLL, { .vop_poll = fifo_poll },
139 VOPNAME_PATHCONF, { .vop_pathconf = fifo_pathconf },
140 VOPNAME_DISPOSE, { .error = fs_error },
141 VOPNAME_SETSECATTR, { .vop_setsecattr = fifo_setsecattr },
142 VOPNAME_GETSECATTR, { .vop_getsecattr = fifo_getsecattr },
143 NULL, NULL
147 * Return the fifoinfo structure.
149 struct streamtab *
150 fifo_getinfo()
152 return (&fifoinfo);
156 * Open and stream a FIFO.
157 * If this is the first open of the file (FIFO is not streaming),
158 * initialize the fifonode and attach a stream to the vnode.
160 * Each end of a fifo must be synchronized with the other end.
161 * If not, the mated end may complete an open, I/O, close sequence
162 * before the end waiting in open ever wakes up.
163 * Note: namefs pipes come through this routine too.
166 fifo_open(vnode_t **vpp, int flag, cred_t *crp, caller_context_t *ct)
168 vnode_t *vp = *vpp;
169 fifonode_t *fnp = VTOF(vp);
170 fifolock_t *fn_lock = fnp->fn_lock;
171 int error;
173 ASSERT(vp->v_type == VFIFO);
174 ASSERT(vn_matchops(vp, fifo_vnodeops));
176 mutex_enter(&fn_lock->flk_lock);
178 * If we are the first reader, wake up any writers that
179 * may be waiting around. wait for all of them to
180 * wake up before proceeding (i.e. fn_wsynccnt == 0)
182 if (flag & FREAD) {
183 fnp->fn_rcnt++; /* record reader present */
184 if (! (fnp->fn_flag & ISPIPE))
185 fnp->fn_rsynccnt++; /* record reader in open */
189 * If we are the first writer, wake up any readers that
190 * may be waiting around. wait for all of them to
191 * wake up before proceeding (i.e. fn_rsynccnt == 0)
193 if (flag & FWRITE) {
194 fnp->fn_wcnt++; /* record writer present */
195 if (! (fnp->fn_flag & ISPIPE))
196 fnp->fn_wsynccnt++; /* record writer in open */
199 * fifo_stropen will take care of twisting the queues on the first
200 * open. The 1 being passed in means twist the queues on the first
201 * open.
203 error = fifo_stropen(vpp, flag, crp, 1, 1);
205 * fifo_stropen() could have replaced vpp
206 * since fifo's are the only thing we need to sync up,
207 * everything else just returns;
208 * Note: don't need to hold lock since ISPIPE can't change
209 * and both old and new vp need to be pipes
211 ASSERT(MUTEX_HELD(&VTOF(*vpp)->fn_lock->flk_lock));
212 if (fnp->fn_flag & ISPIPE) {
213 ASSERT(VTOF(*vpp)->fn_flag & ISPIPE);
214 ASSERT(VTOF(*vpp)->fn_rsynccnt == 0);
215 ASSERT(VTOF(*vpp)->fn_rsynccnt == 0);
217 * XXX note: should probably hold locks, but
218 * These values should not be changing
220 ASSERT(fnp->fn_rsynccnt == 0);
221 ASSERT(fnp->fn_wsynccnt == 0);
222 mutex_exit(&VTOF(*vpp)->fn_lock->flk_lock);
223 return (error);
226 * vp can't change for FIFOS
228 ASSERT(vp == *vpp);
230 * If we are opening for read (or writer)
231 * indicate that the reader (or writer) is done with open
232 * if there is a writer (or reader) waiting for us, wake them up
233 * and indicate that at least 1 read (or write) open has occurred
234 * this is need in the event the read (or write) side closes
235 * before the writer (or reader) has a chance to wake up
236 * i.e. it sees that a reader (or writer) was once there
238 if (flag & FREAD) {
239 fnp->fn_rsynccnt--; /* reader done with open */
240 if (fnp->fn_flag & FIFOSYNC) {
242 * This indicates that a read open has occurred
243 * Only need to set if writer is actually asleep
244 * Flag will be consumed by writer.
246 fnp->fn_flag |= FIFOROCR;
247 cv_broadcast(&fnp->fn_wait_cv);
250 if (flag & FWRITE) {
251 fnp->fn_wsynccnt--; /* writer done with open */
252 if (fnp->fn_flag & FIFOSYNC) {
254 * This indicates that a write open has occurred
255 * Only need to set if reader is actually asleep
256 * Flag will be consumed by reader.
258 fnp->fn_flag |= FIFOWOCR;
259 cv_broadcast(&fnp->fn_wait_cv);
263 fnp->fn_flag &= ~FIFOSYNC;
266 * errors don't wait around.. just return
267 * Note: XXX other end will wake up and continue despite error.
268 * There is no defined semantic on the correct course of option
269 * so we do what we've done in the past
271 if (error != 0) {
272 mutex_exit(&fnp->fn_lock->flk_lock);
273 goto done;
275 ASSERT(fnp->fn_rsynccnt <= fnp->fn_rcnt);
276 ASSERT(fnp->fn_wsynccnt <= fnp->fn_wcnt);
278 * FIFOWOCR (or FIFOROCR) indicates that the writer (or reader)
279 * has woken us up and is done with open (this way, if the other
280 * end has made it to close, we don't block forever in open)
281 * fn_wnct == fn_wsynccnt (or fn_rcnt == fn_rsynccnt) indicates
282 * that no writer (or reader) has yet made it through open
283 * This has the side benefit of that the first
284 * reader (or writer) will wait until the other end finishes open
286 if (flag & FREAD) {
287 while ((fnp->fn_flag & FIFOWOCR) == 0 &&
288 fnp->fn_wcnt == fnp->fn_wsynccnt) {
289 if (flag & (FNDELAY|FNONBLOCK)) {
290 mutex_exit(&fnp->fn_lock->flk_lock);
291 goto done;
293 fnp->fn_insync++;
294 fnp->fn_flag |= FIFOSYNC;
295 if (!cv_wait_sig_swap(&fnp->fn_wait_cv,
296 &fnp->fn_lock->flk_lock)) {
298 * Last reader to wakeup clear writer
299 * Clear both writer and reader open
300 * occurred flag incase other end is O_RDWR
302 if (--fnp->fn_insync == 0 &&
303 fnp->fn_flag & FIFOWOCR) {
304 fnp->fn_flag &= ~(FIFOWOCR|FIFOROCR);
306 mutex_exit(&fnp->fn_lock->flk_lock);
307 (void) fifo_close(*vpp, flag, 1, 0, crp, ct);
308 error = EINTR;
309 goto done;
312 * Last reader to wakeup clear writer open occurred flag
313 * Clear both writer and reader open occurred flag
314 * incase other end is O_RDWR
316 if (--fnp->fn_insync == 0 &&
317 fnp->fn_flag & FIFOWOCR) {
318 fnp->fn_flag &= ~(FIFOWOCR|FIFOROCR);
319 break;
322 } else if (flag & FWRITE) {
323 while ((fnp->fn_flag & FIFOROCR) == 0 &&
324 fnp->fn_rcnt == fnp->fn_rsynccnt) {
325 if ((flag & (FNDELAY|FNONBLOCK)) && fnp->fn_rcnt == 0) {
326 mutex_exit(&fnp->fn_lock->flk_lock);
327 (void) fifo_close(*vpp, flag, 1, 0, crp, ct);
328 error = ENXIO;
329 goto done;
331 fnp->fn_flag |= FIFOSYNC;
332 fnp->fn_insync++;
333 if (!cv_wait_sig_swap(&fnp->fn_wait_cv,
334 &fnp->fn_lock->flk_lock)) {
336 * Last writer to wakeup clear
337 * Clear both writer and reader open
338 * occurred flag in case other end is O_RDWR
340 if (--fnp->fn_insync == 0 &&
341 (fnp->fn_flag & FIFOROCR) != 0) {
342 fnp->fn_flag &= ~(FIFOWOCR|FIFOROCR);
344 mutex_exit(&fnp->fn_lock->flk_lock);
345 (void) fifo_close(*vpp, flag, 1, 0, crp, ct);
346 error = EINTR;
347 goto done;
350 * Last writer to wakeup clear reader open occurred flag
351 * Clear both writer and reader open
352 * occurred flag in case other end is O_RDWR
354 if (--fnp->fn_insync == 0 &&
355 (fnp->fn_flag & FIFOROCR) != 0) {
356 fnp->fn_flag &= ~(FIFOWOCR|FIFOROCR);
357 break;
361 mutex_exit(&fn_lock->flk_lock);
362 done:
363 return (error);
367 * Close down a stream.
368 * Call cleanlocks() and strclean() on every close.
369 * For last close send hangup message and force
370 * the other end of a named pipe to be unmounted.
371 * Mount guarantees that the mounted end will only call fifo_close()
372 * with a count of 1 when the unmount occurs.
373 * This routine will close down one end of a pipe or FIFO
374 * and free the stream head via strclose()
376 /*ARGSUSED*/
378 fifo_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *crp,
379 caller_context_t *ct)
381 fifonode_t *fnp = VTOF(vp);
382 fifonode_t *fn_dest = fnp->fn_dest;
383 int error = 0;
384 fifolock_t *fn_lock = fnp->fn_lock;
385 queue_t *sd_wrq;
386 vnode_t *fn_dest_vp;
387 int senthang = 0;
389 ASSERT(vp->v_stream != NULL);
391 * clean locks and clear events.
393 (void) cleanlocks(vp, ttoproc(curthread)->p_pid, 0);
394 cleanshares(vp, ttoproc(curthread)->p_pid);
395 strclean(vp);
398 * If a file still has the pipe/FIFO open, return.
400 if (count > 1)
401 return (0);
404 sd_wrq = strvp2wq(vp);
405 mutex_enter(&fn_lock->flk_lock);
408 * wait for pending opens to finish up
409 * note: this also has the side effect of single threading closes
411 while (fn_lock->flk_ocsync)
412 cv_wait(&fn_lock->flk_wait_cv, &fn_lock->flk_lock);
414 fn_lock->flk_ocsync = 1;
416 if (flag & FREAD) {
417 fnp->fn_rcnt--;
420 * If we are last writer wake up sleeping readers
421 * (They'll figure out that there are no more writers
422 * and do the right thing)
423 * send hangup down stream so that stream head will do the
424 * right thing.
426 if (flag & FWRITE) {
427 if (--fnp->fn_wcnt == 0 && fn_dest->fn_rcnt > 0) {
428 if ((fn_dest->fn_flag & (FIFOFAST | FIFOWANTR)) ==
429 (FIFOFAST | FIFOWANTR)) {
431 * While we're at it, clear FIFOWANTW too
432 * Wake up any sleeping readers or
433 * writers.
435 fn_dest->fn_flag &= ~(FIFOWANTR | FIFOWANTW);
436 cv_broadcast(&fn_dest->fn_wait_cv);
439 * This is needed incase the other side
440 * was opened non-blocking. It is the
441 * only way we can tell that wcnt is 0 because
442 * of close instead of never having a writer
444 if (!(fnp->fn_flag & ISPIPE))
445 fnp->fn_flag |= FIFOCLOSE;
447 * Note: sending hangup effectively shuts down
448 * both reader and writer at other end.
450 (void) putnextctl_wait(sd_wrq, M_HANGUP);
451 senthang = 1;
456 * For FIFOs we need to indicate to stream head that last reader
457 * has gone away so that an error is generated
458 * Pipes just need to wake up the other end so that it can
459 * notice this end has gone away.
462 if (fnp->fn_rcnt == 0 && fn_dest->fn_wcnt > 0) {
463 if ((fn_dest->fn_flag & (FIFOFAST | FIFOWANTW)) ==
464 (FIFOFAST | FIFOWANTW)) {
466 * wake up any sleeping writers
468 fn_dest->fn_flag &= ~FIFOWANTW;
469 cv_broadcast(&fn_dest->fn_wait_cv);
474 * if there are still processes with this FIFO open
475 * clear open/close sync flag
476 * and just return;
478 if (--fnp->fn_open > 0) {
479 ASSERT((fnp->fn_rcnt + fnp->fn_wcnt) != 0);
480 fn_lock->flk_ocsync = 0;
481 cv_broadcast(&fn_lock->flk_wait_cv);
482 mutex_exit(&fn_lock->flk_lock);
483 return (0);
487 * Need to send HANGUP if other side is still open
488 * (fnp->fn_rcnt or fnp->fn_wcnt may not be zero (some thread
489 * on this end of the pipe may still be in fifo_open())
491 * Note: we can get here with fn_rcnt and fn_wcnt != 0 if some
492 * thread is blocked somewhere in the fifo_open() path prior to
493 * fifo_stropen() incrementing fn_open. This can occur for
494 * normal FIFOs as well as named pipes. fn_rcnt and
495 * fn_wcnt only indicate attempts to open. fn_open indicates
496 * successful opens. Partially opened FIFOs should proceed
497 * normally; i.e. they will appear to be new opens. Partially
498 * opened pipes will probably fail.
501 if (fn_dest->fn_open && senthang == 0)
502 (void) putnextctl_wait(sd_wrq, M_HANGUP);
506 * If this a pipe and this is the first end to close,
507 * then we have a bit of cleanup work to do.
508 * Mark both ends of pipe as closed.
509 * Wake up anybody blocked at the other end and for named pipes,
510 * Close down this end of the stream
511 * Allow other opens/closes to continue
512 * force an unmount of other end.
513 * Otherwise if this is last close,
514 * flush messages,
515 * close down the stream
516 * allow other opens/closes to continue
518 fnp->fn_flag &= ~FIFOISOPEN;
519 if ((fnp->fn_flag & ISPIPE) && !(fnp->fn_flag & FIFOCLOSE)) {
520 fnp->fn_flag |= FIFOCLOSE;
521 fn_dest->fn_flag |= FIFOCLOSE;
522 if (fnp->fn_flag & FIFOFAST)
523 fifo_fastflush(fnp);
524 if (vp->v_stream != NULL) {
525 mutex_exit(&fn_lock->flk_lock);
526 (void) strclose(vp, flag, crp);
527 mutex_enter(&fn_lock->flk_lock);
529 cv_broadcast(&fn_dest->fn_wait_cv);
531 * allow opens and closes to proceed
532 * Since this end is now closed down, any attempt
533 * to do anything with this end will fail
535 fn_lock->flk_ocsync = 0;
536 cv_broadcast(&fn_lock->flk_wait_cv);
537 fn_dest_vp = FTOV(fn_dest);
539 * if other end of pipe has been opened and it's
540 * a named pipe, unmount it
542 if (fn_dest_vp->v_stream &&
543 (fn_dest_vp->v_stream->sd_flag & STRMOUNT)) {
545 * We must hold the destination vnode because
546 * nm_unmountall() causes close to be called
547 * for the other end of named pipe. This
548 * could free the vnode before we are ready.
550 VN_HOLD(fn_dest_vp);
551 mutex_exit(&fn_lock->flk_lock);
552 error = nm_unmountall(fn_dest_vp, crp);
553 ASSERT(error == 0);
554 VN_RELE(fn_dest_vp);
555 } else {
556 ASSERT(vp->v_count >= 1);
557 mutex_exit(&fn_lock->flk_lock);
559 } else {
560 if (fnp->fn_flag & FIFOFAST)
561 fifo_fastflush(fnp);
562 #if DEBUG
563 fn_dest_vp = FTOV(fn_dest);
564 if (fn_dest_vp->v_stream)
565 ASSERT((fn_dest_vp->v_stream->sd_flag & STRMOUNT) == 0);
566 #endif
567 if (vp->v_stream != NULL) {
568 mutex_exit(&fn_lock->flk_lock);
569 (void) strclose(vp, flag, crp);
570 mutex_enter(&fn_lock->flk_lock);
572 fn_lock->flk_ocsync = 0;
573 cv_broadcast(&fn_lock->flk_wait_cv);
574 cv_broadcast(&fn_dest->fn_wait_cv);
575 mutex_exit(&fn_lock->flk_lock);
577 return (error);
581 * Read from a pipe or FIFO.
582 * return 0 if....
583 * (1) user read request is 0 or no stream
584 * (2) broken pipe with no data
585 * (3) write-only FIFO with no data
586 * (4) no data and FNDELAY flag is set.
587 * Otherwise return
588 * EAGAIN if FNONBLOCK is set and no data to read
589 * EINTR if signal received while waiting for data
591 * While there is no data to read....
592 * - if the NDELAY/NONBLOCK flag is set, return 0/EAGAIN.
593 * - wait for a write.
596 /*ARGSUSED*/
598 static int
599 fifo_read(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *crp,
600 caller_context_t *ct)
602 fifonode_t *fnp = VTOF(vp);
603 fifonode_t *fn_dest;
604 fifolock_t *fn_lock = fnp->fn_lock;
605 int error = 0;
606 mblk_t *bp;
608 ASSERT(vp->v_stream != NULL);
609 if (uiop->uio_resid == 0)
610 return (0);
612 mutex_enter(&fn_lock->flk_lock);
614 TRACE_2(TR_FAC_FIFO, TR_FIFOREAD_IN, "fifo_read in:%p fnp %p", vp, fnp);
616 if (! (fnp->fn_flag & FIFOFAST))
617 goto stream_mode;
619 fn_dest = fnp->fn_dest;
621 * Check for data on our input queue
624 while (fnp->fn_count == 0) {
626 * No data on first attempt and no writer, then EOF
628 if (fn_dest->fn_wcnt == 0 || fn_dest->fn_rcnt == 0) {
629 mutex_exit(&fn_lock->flk_lock);
630 return (0);
633 * no data found.. if non-blocking, return EAGAIN
634 * otherwise 0.
636 if (uiop->uio_fmode & (FNDELAY|FNONBLOCK)) {
637 mutex_exit(&fn_lock->flk_lock);
638 if (uiop->uio_fmode & FNONBLOCK)
639 return (EAGAIN);
640 return (0);
644 * Note: FIFOs can get here with FIFOCLOSE set if
645 * write side is in the middle of opeining after
646 * it once closed. Pipes better not have FIFOCLOSE set
648 ASSERT((fnp->fn_flag & (ISPIPE|FIFOCLOSE)) !=
649 (ISPIPE|FIFOCLOSE));
651 * wait for data
653 fnp->fn_flag |= FIFOWANTR;
655 TRACE_1(TR_FAC_FIFO, TR_FIFOREAD_WAIT, "fiforead wait: %p", vp);
657 if (!cv_wait_sig_swap(&fnp->fn_wait_cv,
658 &fn_lock->flk_lock)) {
659 error = EINTR;
660 goto done;
663 TRACE_1(TR_FAC_FIFO, TR_FIFOREAD_WAKE,
664 "fiforead awake: %p", vp);
667 * check to make sure we are still in fast mode
669 if (!(fnp->fn_flag & FIFOFAST))
670 goto stream_mode;
673 ASSERT(fnp->fn_mp != NULL);
675 /* For pipes copy should not bypass cache */
676 uiop->uio_extflg |= UIO_COPY_CACHED;
678 do {
679 int bpsize = MBLKL(fnp->fn_mp);
680 int uiosize = MIN(bpsize, uiop->uio_resid);
682 error = uiomove(fnp->fn_mp->b_rptr, uiosize, UIO_READ, uiop);
683 if (error != 0)
684 break;
686 fnp->fn_count -= uiosize;
688 if (bpsize <= uiosize) {
689 bp = fnp->fn_mp;
690 fnp->fn_mp = fnp->fn_mp->b_cont;
691 freeb(bp);
693 if (uiop->uio_resid == 0)
694 break;
696 while (fnp->fn_mp == NULL && fn_dest->fn_wwaitcnt > 0) {
697 ASSERT(fnp->fn_count == 0);
699 if (uiop->uio_fmode & (FNDELAY|FNONBLOCK))
700 goto trywake;
703 * We've consumed all available data but there
704 * are threads waiting to write more, let them
705 * proceed before bailing.
708 fnp->fn_flag |= FIFOWANTR;
709 fifo_wakewriter(fn_dest, fn_lock);
711 if (!cv_wait_sig(&fnp->fn_wait_cv,
712 &fn_lock->flk_lock))
713 goto trywake;
715 if (!(fnp->fn_flag & FIFOFAST))
716 goto stream_mode;
718 } else {
719 fnp->fn_mp->b_rptr += uiosize;
720 ASSERT(uiop->uio_resid == 0);
722 } while (uiop->uio_resid != 0 && fnp->fn_mp != NULL);
724 trywake:
725 ASSERT(msgdsize(fnp->fn_mp) == fnp->fn_count);
728 * wake up any blocked writers, processes
729 * sleeping on POLLWRNORM, or processes waiting for SIGPOLL
730 * Note: checking for fn_count < Fifohiwat emulates
731 * STREAMS functionality when low water mark is 0
733 if (fn_dest->fn_flag & (FIFOWANTW | FIFOHIWATW) &&
734 fnp->fn_count < Fifohiwat) {
735 fifo_wakewriter(fn_dest, fn_lock);
737 goto done;
740 * FIFO is in streams mode.. let the stream head handle it
742 stream_mode:
744 mutex_exit(&fn_lock->flk_lock);
745 TRACE_1(TR_FAC_FIFO,
746 TR_FIFOREAD_STREAM, "fifo_read stream_mode:%p", vp);
748 error = strread(vp, uiop, crp);
750 mutex_enter(&fn_lock->flk_lock);
752 done:
754 * vnode update access time
756 if (error == 0) {
757 time_t now = gethrestime_sec();
759 if (fnp->fn_flag & ISPIPE)
760 fnp->fn_dest->fn_atime = now;
761 fnp->fn_atime = now;
763 TRACE_2(TR_FAC_FIFO, TR_FIFOREAD_OUT,
764 "fifo_read out:%p error %d", vp, error);
765 mutex_exit(&fn_lock->flk_lock);
766 return (error);
770 * send SIGPIPE and return EPIPE if ...
771 * (1) broken pipe (essentially, reader is gone)
772 * (2) FIFO is not open for reading
773 * return 0 if...
774 * (1) no stream
775 * (2) user write request is for 0 bytes and SW_SNDZERO is not set
776 * Note: SW_SNDZERO can't be set in fast mode
777 * While the stream is flow controlled....
778 * - if the NDELAY/NONBLOCK flag is set, return 0/EAGAIN.
779 * - unlock the fifonode and sleep waiting for a reader.
780 * - if a pipe and it has a mate, sleep waiting for its mate
781 * to read.
783 /*ARGSUSED*/
784 static int
785 fifo_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *crp,
786 caller_context_t *ct)
788 struct fifonode *fnp, *fn_dest;
789 fifolock_t *fn_lock;
790 struct stdata *stp;
791 int error = 0;
792 int write_size;
793 int size;
794 int fmode;
795 mblk_t *bp;
796 boolean_t hotread;
798 ASSERT(vp->v_stream);
799 uiop->uio_loffset = 0;
800 stp = vp->v_stream;
803 * remember original number of bytes requested. Used to determine if
804 * we actually have written anything at all
806 write_size = uiop->uio_resid;
809 * only send zero-length messages if SW_SNDZERO is set
810 * Note: we will be in streams mode if SW_SNDZERO is set
811 * XXX this streams interface should not be exposed
813 if ((write_size == 0) && !(stp->sd_wput_opt & SW_SNDZERO))
814 return (0);
816 fnp = VTOF(vp);
817 fn_lock = fnp->fn_lock;
818 fn_dest = fnp->fn_dest;
820 mutex_enter(&fn_lock->flk_lock);
822 TRACE_3(TR_FAC_FIFO, TR_FIFOWRITE_IN,
823 "fifo_write in:%p fnp %p size %d", vp, fnp, write_size);
826 * oops, no readers, error
828 if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
829 goto epipe;
833 * if we are not in fast mode, let streams handle it
835 if (!(fnp->fn_flag & FIFOFAST))
836 goto stream_mode;
838 fmode = uiop->uio_fmode & (FNDELAY|FNONBLOCK);
840 /* For pipes copy should not bypass cache */
841 uiop->uio_extflg |= UIO_COPY_CACHED;
843 do {
845 * check to make sure we are not over high water mark
847 while (fn_dest->fn_count >= Fifohiwat) {
849 * Indicate that we have gone over high
850 * water mark
853 * if non-blocking, return
854 * only happens first time through loop
856 if (fmode) {
857 fnp->fn_flag |= FIFOHIWATW;
858 if (uiop->uio_resid == write_size) {
859 mutex_exit(&fn_lock->flk_lock);
860 if (fmode & FNDELAY)
861 return (0);
862 else
863 return (EAGAIN);
865 goto done;
869 * wait for things to drain
871 fnp->fn_flag |= FIFOWANTW;
872 fnp->fn_wwaitcnt++;
873 TRACE_1(TR_FAC_FIFO, TR_FIFOWRITE_WAIT,
874 "fifo_write wait: %p", vp);
875 if (!cv_wait_sig_swap(&fnp->fn_wait_cv,
876 &fn_lock->flk_lock)) {
877 error = EINTR;
878 fnp->fn_wwaitcnt--;
879 fifo_wakereader(fn_dest, fn_lock);
880 goto done;
882 fnp->fn_wwaitcnt--;
884 TRACE_1(TR_FAC_FIFO, TR_FIFOWRITE_WAKE,
885 "fifo_write wake: %p", vp);
888 * check to make sure we're still in fast mode
890 if (!(fnp->fn_flag & FIFOFAST))
891 goto stream_mode;
894 * make sure readers didn't go away
896 if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
897 goto epipe;
901 * If the write will put us over the high water mark,
902 * then we must break the message up into PIPE_BUF
903 * chunks to stay compliant with STREAMS
905 if (uiop->uio_resid + fn_dest->fn_count > Fifohiwat)
906 size = MIN(uiop->uio_resid, PIPE_BUF);
907 else
908 size = uiop->uio_resid;
911 * We don't need to hold flk_lock across the allocb() and
912 * uiomove(). However, on a multiprocessor machine where both
913 * the reader and writer thread are on cpu's, we must be
914 * careful to only drop the lock if there's data to be read.
915 * This forces threads entering fifo_read() to spin or block
916 * on flk_lock, rather than acquiring flk_lock only to
917 * discover there's no data to read and being forced to go
918 * back to sleep, only to be woken up microseconds later by
919 * this writer thread.
921 hotread = fn_dest->fn_count > 0;
922 if (hotread) {
923 if (!fifo_stayfast_enter(fnp))
924 goto stream_mode;
925 mutex_exit(&fn_lock->flk_lock);
928 ASSERT(size != 0);
930 * Align the mblk with the user data so that
931 * copying in the data can take advantage of
932 * the double word alignment
934 if ((bp = allocb(size + 8, BPRI_MED)) == NULL) {
935 if (!hotread)
936 mutex_exit(&fn_lock->flk_lock);
938 error = strwaitbuf(size, BPRI_MED);
940 mutex_enter(&fn_lock->flk_lock);
942 if (hotread) {
944 * As we dropped the mutex for a moment, we
945 * need to wake up any thread waiting to be
946 * allowed to go from fast mode to stream mode.
948 fifo_stayfast_exit(fnp);
950 if (error != 0) {
951 goto done;
954 * check to make sure we're still in fast mode
956 if (!(fnp->fn_flag & FIFOFAST))
957 goto stream_mode;
960 * make sure readers didn't go away
962 if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
963 goto epipe;
966 * some other thread could have gotten in
967 * need to go back and check hi water mark
969 continue;
971 bp->b_rptr += ((uintptr_t)uiop->uio_iov->iov_base & 0x7);
972 bp->b_wptr = bp->b_rptr + size;
973 error = uiomove((caddr_t)bp->b_rptr, size, UIO_WRITE, uiop);
974 if (hotread) {
975 mutex_enter(&fn_lock->flk_lock);
977 * As we dropped the mutex for a moment, we need to:
978 * - wake up any thread waiting to be allowed to go
979 * from fast mode to stream mode,
980 * - make sure readers didn't go away.
982 fifo_stayfast_exit(fnp);
983 if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
984 freeb(bp);
985 goto epipe;
989 if (error != 0) {
990 freeb(bp);
991 goto done;
994 fn_dest->fn_count += size;
995 if (fn_dest->fn_mp != NULL) {
996 fn_dest->fn_tail->b_cont = bp;
997 fn_dest->fn_tail = bp;
998 } else {
999 fn_dest->fn_mp = fn_dest->fn_tail = bp;
1001 * This is the first bit of data; wake up any sleeping
1002 * readers, processes blocked in poll, and those
1003 * expecting a SIGPOLL.
1005 fifo_wakereader(fn_dest, fn_lock);
1007 } while (uiop->uio_resid != 0);
1009 goto done;
1011 stream_mode:
1013 * streams mode
1014 * let the stream head handle the write
1016 ASSERT(MUTEX_HELD(&fn_lock->flk_lock));
1018 mutex_exit(&fn_lock->flk_lock);
1019 TRACE_1(TR_FAC_FIFO,
1020 TR_FIFOWRITE_STREAM, "fifo_write stream_mode:%p", vp);
1022 error = strwrite(vp, uiop, crp);
1024 mutex_enter(&fn_lock->flk_lock);
1026 done:
1028 * update vnode modification and change times
1029 * make sure there were no errors and some data was transferred
1031 if (error == 0 && write_size != uiop->uio_resid) {
1032 time_t now = gethrestime_sec();
1034 if (fnp->fn_flag & ISPIPE) {
1035 fn_dest->fn_mtime = fn_dest->fn_ctime = now;
1037 fnp->fn_mtime = fnp->fn_ctime = now;
1038 } else if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
1039 goto epipe;
1041 TRACE_3(TR_FAC_FIFO, TR_FIFOWRITE_OUT,
1042 "fifo_write out: vp %p error %d fnp %p", vp, error, fnp);
1043 mutex_exit(&fn_lock->flk_lock);
1044 return (error);
1045 epipe:
1046 error = EPIPE;
1047 TRACE_3(TR_FAC_FIFO, TR_FIFOWRITE_OUT,
1048 "fifo_write out: vp %p error %d fnp %p", vp, error, fnp);
1049 mutex_exit(&fn_lock->flk_lock);
1050 tsignal(curthread, SIGPIPE);
1051 return (error);
1054 /*ARGSUSED6*/
1055 static int
1056 fifo_ioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1057 cred_t *cr, int *rvalp, caller_context_t *ct)
1060 * Just a quick check
1061 * Once we go to streams mode we don't ever revert back
1062 * So we do this quick check so as not to incur the overhead
1063 * associated with acquiring the lock
1065 return ((VTOF(vp)->fn_flag & FIFOFAST) ?
1066 fifo_fastioctl(vp, cmd, arg, mode, cr, rvalp) :
1067 fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1070 static inline int
1071 fifo_ioctl_getpeercred(fifonode_t *fnp, intptr_t arg, int mode)
1073 k_peercred_t *kp = (k_peercred_t *)arg;
1075 if (mode == FKIOCTL && fnp->fn_pcredp != NULL) {
1076 crhold(fnp->fn_pcredp);
1077 kp->pc_cr = fnp->fn_pcredp;
1078 kp->pc_cpid = fnp->fn_cpid;
1079 return (0);
1080 } else {
1081 return (ENOTSUP);
1085 static int
1086 fifo_fastioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1087 cred_t *cr, int *rvalp)
1089 fifonode_t *fnp = VTOF(vp);
1090 fifonode_t *fn_dest;
1091 int error = 0;
1092 fifolock_t *fn_lock = fnp->fn_lock;
1093 int cnt;
1096 * tty operations not allowed
1098 if (((cmd & IOCTYPE) == LDIOC) ||
1099 ((cmd & IOCTYPE) == tIOC) ||
1100 ((cmd & IOCTYPE) == TIOC)) {
1101 return (EINVAL);
1104 mutex_enter(&fn_lock->flk_lock);
1106 if (!(fnp->fn_flag & FIFOFAST)) {
1107 goto stream_mode;
1110 switch (cmd) {
1113 * Things we can't handle
1114 * These will switch us to streams mode.
1116 default:
1117 case I_STR:
1118 case I_SRDOPT:
1119 case I_PUSH:
1120 case I_FDINSERT:
1121 case I_SENDFD:
1122 case I_RECVFD:
1123 case I_E_RECVFD:
1124 case I_ATMARK:
1125 case I_CKBAND:
1126 case I_GETBAND:
1127 case I_SWROPT:
1128 goto turn_fastoff;
1131 * Things that don't do damage
1132 * These things don't adjust the state of the
1133 * stream head (i_setcltime does, but we don't care)
1135 case I_FIND:
1136 case I_GETSIG:
1137 case FIONBIO:
1138 case FIOASYNC:
1139 case I_GRDOPT: /* probably should not get this, but no harm */
1140 case I_GWROPT:
1141 case I_LIST:
1142 case I_SETCLTIME:
1143 case I_GETCLTIME:
1144 mutex_exit(&fn_lock->flk_lock);
1145 return (strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp));
1147 case I_CANPUT:
1149 * We can only handle normal band canputs.
1150 * XXX : We could just always go to stream mode; after all
1151 * canput is a streams semantics type thing
1153 if (arg != 0) {
1154 goto turn_fastoff;
1156 *rvalp = (fnp->fn_dest->fn_count < Fifohiwat) ? 1 : 0;
1157 mutex_exit(&fn_lock->flk_lock);
1158 return (0);
1160 case I_NREAD:
1162 * This may seem a bit silly for non-streams semantics,
1163 * (After all, if they really want a message, they'll
1164 * probably use getmsg() anyway). but it doesn't hurt
1166 error = copyout((caddr_t)&fnp->fn_count, (caddr_t)arg,
1167 sizeof (cnt));
1168 if (error == 0) {
1169 *rvalp = (fnp->fn_count == 0) ? 0 : 1;
1171 break;
1173 case FIORDCHK:
1174 *rvalp = fnp->fn_count;
1175 break;
1177 case I_PEEK:
1179 STRUCT_DECL(strpeek, strpeek);
1180 struct uio uio;
1181 struct iovec iov;
1182 int count;
1183 mblk_t *bp;
1184 int len;
1186 STRUCT_INIT(strpeek, mode);
1188 if (fnp->fn_count == 0) {
1189 *rvalp = 0;
1190 break;
1193 error = copyin((caddr_t)arg, STRUCT_BUF(strpeek),
1194 STRUCT_SIZE(strpeek));
1195 if (error)
1196 break;
1199 * can't have any high priority message when in fast mode
1201 if (STRUCT_FGET(strpeek, flags) & RS_HIPRI) {
1202 *rvalp = 0;
1203 break;
1206 len = STRUCT_FGET(strpeek, databuf.maxlen);
1207 if (len <= 0) {
1208 STRUCT_FSET(strpeek, databuf.len, len);
1209 } else {
1210 iov.iov_base = STRUCT_FGETP(strpeek, databuf.buf);
1211 iov.iov_len = len;
1212 uio.uio_iov = &iov;
1213 uio.uio_iovcnt = 1;
1214 uio.uio_loffset = 0;
1215 uio.uio_segflg = UIO_USERSPACE;
1216 uio.uio_fmode = 0;
1217 /* For pipes copy should not bypass cache */
1218 uio.uio_extflg = UIO_COPY_CACHED;
1219 uio.uio_resid = iov.iov_len;
1220 count = fnp->fn_count;
1221 bp = fnp->fn_mp;
1222 while (count > 0 && uio.uio_resid) {
1223 cnt = MIN(uio.uio_resid, MBLKL(bp));
1224 if ((error = uiomove((char *)bp->b_rptr, cnt,
1225 UIO_READ, &uio)) != 0) {
1226 break;
1228 count -= cnt;
1229 bp = bp->b_cont;
1231 STRUCT_FSET(strpeek, databuf.len, len - uio.uio_resid);
1233 STRUCT_FSET(strpeek, flags, 0);
1234 STRUCT_FSET(strpeek, ctlbuf.len, -1);
1236 error = copyout(STRUCT_BUF(strpeek), (caddr_t)arg,
1237 STRUCT_SIZE(strpeek));
1238 if (error == 0 && len >= 0)
1239 *rvalp = 1;
1240 break;
1243 case FIONREAD:
1245 * let user know total number of bytes in message queue
1247 error = copyout((caddr_t)&fnp->fn_count, (caddr_t)arg,
1248 sizeof (fnp->fn_count));
1249 if (error == 0)
1250 *rvalp = 0;
1251 break;
1253 case I_SETSIG:
1255 * let streams set up the signal masking for us
1256 * we just check to see if it's set
1257 * XXX : this interface should not be visible
1258 * i.e. STREAM's framework is exposed.
1260 error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
1261 if (vp->v_stream->sd_sigflags & (S_INPUT|S_RDNORM|S_WRNORM))
1262 fnp->fn_flag |= FIFOSETSIG;
1263 else
1264 fnp->fn_flag &= ~FIFOSETSIG;
1265 break;
1267 case I_FLUSH:
1269 * flush them message queues
1271 if (arg & ~FLUSHRW) {
1272 error = EINVAL;
1273 break;
1275 if (arg & FLUSHR) {
1276 fifo_fastflush(fnp);
1278 fn_dest = fnp->fn_dest;
1279 if ((arg & FLUSHW)) {
1280 fifo_fastflush(fn_dest);
1283 * wake up any sleeping readers or writers
1284 * (waking readers probably doesn't make sense, but it
1285 * doesn't hurt; i.e. we just got rid of all the data
1286 * what's to read ?)
1288 if (fn_dest->fn_flag & (FIFOWANTW | FIFOWANTR)) {
1289 fn_dest->fn_flag &= ~(FIFOWANTW | FIFOWANTR);
1290 cv_broadcast(&fn_dest->fn_wait_cv);
1292 *rvalp = 0;
1293 break;
1296 * Since no band data can ever get on a fifo in fast mode
1297 * just return 0.
1299 case I_FLUSHBAND:
1300 error = 0;
1301 *rvalp = 0;
1302 break;
1304 case _I_GETPEERCRED:
1305 error = fifo_ioctl_getpeercred(fnp, arg, mode);
1306 break;
1309 * invalid calls for stream head or fifos
1312 case I_POP: /* shouldn't happen */
1313 case I_LOOK:
1314 case I_LINK:
1315 case I_PLINK:
1316 case I_UNLINK:
1317 case I_PUNLINK:
1320 * more invalid tty type of ioctls
1323 case SRIOCSREDIR:
1324 case SRIOCISREDIR:
1325 error = EINVAL;
1326 break;
1329 mutex_exit(&fn_lock->flk_lock);
1330 return (error);
1332 turn_fastoff:
1333 fifo_fastoff(fnp);
1335 stream_mode:
1337 * streams mode
1339 mutex_exit(&fn_lock->flk_lock);
1340 return (fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1345 * FIFO is in STREAMS mode; STREAMS framework does most of the work.
1347 static int
1348 fifo_strioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1349 cred_t *cr, int *rvalp)
1351 fifonode_t *fnp = VTOF(vp);
1352 int error;
1353 fifolock_t *fn_lock;
1355 if (cmd == _I_GETPEERCRED)
1356 return (fifo_ioctl_getpeercred(fnp, arg, mode));
1358 error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
1360 switch (cmd) {
1362 * The FIFOSEND flag is set to inform other processes that a file
1363 * descriptor is pending at the stream head of this pipe.
1364 * The flag is cleared and the sending process is awoken when
1365 * this process has completed receiving the file descriptor.
1366 * XXX This could become out of sync if the process does I_SENDFDs
1367 * and opens on connld attached to the same pipe.
1369 case I_RECVFD:
1370 case I_E_RECVFD:
1371 if (error == 0) {
1372 fn_lock = fnp->fn_lock;
1373 mutex_enter(&fn_lock->flk_lock);
1374 if (fnp->fn_flag & FIFOSEND) {
1375 fnp->fn_flag &= ~FIFOSEND;
1376 cv_broadcast(&fnp->fn_dest->fn_wait_cv);
1378 mutex_exit(&fn_lock->flk_lock);
1380 break;
1381 default:
1382 break;
1385 return (error);
1389 * If shadowing a vnode (FIFOs), apply the VOP_GETATTR to the shadowed
1390 * vnode to Obtain the node information. If not shadowing (pipes), obtain
1391 * the node information from the credentials structure.
1394 fifo_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *crp,
1395 caller_context_t *ct)
1397 int error = 0;
1398 fifonode_t *fnp = VTOF(vp);
1399 queue_t *qp;
1400 qband_t *bandp;
1401 fifolock_t *fn_lock = fnp->fn_lock;
1403 if (fnp->fn_realvp) {
1405 * for FIFOs or mounted pipes
1407 if (error = VOP_GETATTR(fnp->fn_realvp, vap, flags, crp, ct))
1408 return (error);
1409 mutex_enter(&fn_lock->flk_lock);
1410 /* set current times from fnode, even if older than vnode */
1411 vap->va_atime.tv_sec = fnp->fn_atime;
1412 vap->va_atime.tv_nsec = 0;
1413 vap->va_mtime.tv_sec = fnp->fn_mtime;
1414 vap->va_mtime.tv_nsec = 0;
1415 vap->va_ctime.tv_sec = fnp->fn_ctime;
1416 vap->va_ctime.tv_nsec = 0;
1417 } else {
1419 * for non-attached/ordinary pipes
1421 vap->va_mode = 0;
1422 mutex_enter(&fn_lock->flk_lock);
1423 vap->va_atime.tv_sec = fnp->fn_atime;
1424 vap->va_atime.tv_nsec = 0;
1425 vap->va_mtime.tv_sec = fnp->fn_mtime;
1426 vap->va_mtime.tv_nsec = 0;
1427 vap->va_ctime.tv_sec = fnp->fn_ctime;
1428 vap->va_ctime.tv_nsec = 0;
1429 vap->va_uid = crgetuid(crp);
1430 vap->va_gid = crgetgid(crp);
1431 vap->va_nlink = 0;
1432 vap->va_fsid = fifodev;
1433 vap->va_nodeid = (ino64_t)fnp->fn_ino;
1434 vap->va_rdev = 0;
1436 vap->va_type = VFIFO;
1437 vap->va_blksize = PIPE_BUF;
1439 * Size is number of un-read bytes at the stream head and
1440 * nblocks is the unread bytes expressed in blocks.
1442 if (vp->v_stream && (fnp->fn_flag & FIFOISOPEN)) {
1443 if ((fnp->fn_flag & FIFOFAST)) {
1444 vap->va_size = (u_offset_t)fnp->fn_count;
1445 } else {
1446 qp = RD((strvp2wq(vp)));
1447 vap->va_size = (u_offset_t)qp->q_count;
1448 if (qp->q_nband != 0) {
1449 mutex_enter(QLOCK(qp));
1450 for (bandp = qp->q_bandp; bandp;
1451 bandp = bandp->qb_next)
1452 vap->va_size += bandp->qb_count;
1453 mutex_exit(QLOCK(qp));
1456 vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size);
1457 } else {
1458 vap->va_size = (u_offset_t)0;
1459 vap->va_nblocks = (fsblkcnt64_t)0;
1461 mutex_exit(&fn_lock->flk_lock);
1462 vap->va_seq = 0;
1463 return (0);
1467 * If shadowing a vnode, apply the VOP_SETATTR to it, and to the fnode.
1468 * Otherwise, set the time and return 0.
1471 fifo_setattr(
1472 vnode_t *vp,
1473 vattr_t *vap,
1474 int flags,
1475 cred_t *crp,
1476 caller_context_t *ctp)
1478 fifonode_t *fnp = VTOF(vp);
1479 int error = 0;
1480 fifolock_t *fn_lock;
1482 if (fnp->fn_realvp)
1483 error = VOP_SETATTR(fnp->fn_realvp, vap, flags, crp, ctp);
1484 if (error == 0) {
1485 fn_lock = fnp->fn_lock;
1486 mutex_enter(&fn_lock->flk_lock);
1487 if (vap->va_mask & AT_ATIME)
1488 fnp->fn_atime = vap->va_atime.tv_sec;
1489 if (vap->va_mask & AT_MTIME)
1490 fnp->fn_mtime = vap->va_mtime.tv_sec;
1491 fnp->fn_ctime = gethrestime_sec();
1492 mutex_exit(&fn_lock->flk_lock);
1494 return (error);
1498 * If shadowing a vnode, apply VOP_ACCESS to it.
1499 * Otherwise, return 0 (allow all access).
1502 fifo_access(vnode_t *vp, int mode, int flags, cred_t *crp, caller_context_t *ct)
1504 if (VTOF(vp)->fn_realvp)
1505 return (VOP_ACCESS(VTOF(vp)->fn_realvp, mode, flags, crp, ct));
1506 else
1507 return (0);
1511 * This can be called if creat or an open with O_CREAT is done on the root
1512 * of a lofs mount where the mounted entity is a fifo.
1514 /*ARGSUSED*/
1515 static int
1516 fifo_create(struct vnode *dvp, char *name, vattr_t *vap, enum vcexcl excl,
1517 int mode, struct vnode **vpp, struct cred *cr, int flag,
1518 caller_context_t *ct, vsecattr_t *vsecp)
1520 int error;
1522 ASSERT(dvp && (dvp->v_flag & VROOT) && *name == '\0');
1523 if (excl == NONEXCL) {
1524 if (mode && (error = fifo_access(dvp, mode, 0, cr, ct)))
1525 return (error);
1526 VN_HOLD(dvp);
1527 return (0);
1529 return (EEXIST);
1533 * If shadowing a vnode, apply the VOP_FSYNC to it.
1534 * Otherwise, return 0.
1537 fifo_fsync(vnode_t *vp, int syncflag, cred_t *crp, caller_context_t *ct)
1539 fifonode_t *fnp = VTOF(vp);
1540 vattr_t va;
1542 if (fnp->fn_realvp == NULL)
1543 return (0);
1545 bzero((caddr_t)&va, sizeof (va));
1546 va.va_mask = AT_MTIME | AT_ATIME;
1547 if (VOP_GETATTR(fnp->fn_realvp, &va, 0, crp, ct) == 0) {
1548 va.va_mask = 0;
1549 if (fnp->fn_mtime > va.va_mtime.tv_sec) {
1550 va.va_mtime.tv_sec = fnp->fn_mtime;
1551 va.va_mask = AT_MTIME;
1553 if (fnp->fn_atime > va.va_atime.tv_sec) {
1554 va.va_atime.tv_sec = fnp->fn_atime;
1555 va.va_mask |= AT_ATIME;
1557 if (va.va_mask != 0)
1558 (void) VOP_SETATTR(fnp->fn_realvp, &va, 0, crp, ct);
1560 return (VOP_FSYNC(fnp->fn_realvp, syncflag, crp, ct));
1564 * Called when the upper level no longer holds references to the
1565 * vnode. Sync the file system and free the fifonode.
1567 void
1568 fifo_inactive(vnode_t *vp, cred_t *crp, caller_context_t *ct)
1570 fifonode_t *fnp;
1571 fifolock_t *fn_lock;
1573 mutex_enter(&ftable_lock);
1574 mutex_enter(&vp->v_lock);
1575 ASSERT(vp->v_count >= 1);
1576 if (--vp->v_count != 0) {
1578 * Somebody accessed the fifo before we got a chance to
1579 * remove it. They will remove it when they do a vn_rele.
1581 mutex_exit(&vp->v_lock);
1582 mutex_exit(&ftable_lock);
1583 return;
1585 mutex_exit(&vp->v_lock);
1587 fnp = VTOF(vp);
1590 * remove fifo from fifo list so that no other process
1591 * can grab it.
1592 * Drop the reference count on the fifo node's
1593 * underlying vfs.
1595 if (fnp->fn_realvp) {
1596 (void) fiforemove(fnp);
1597 mutex_exit(&ftable_lock);
1598 (void) fifo_fsync(vp, FSYNC, crp, ct);
1599 VN_RELE(fnp->fn_realvp);
1600 VFS_RELE(vp->v_vfsp);
1601 vp->v_vfsp = NULL;
1602 } else
1603 mutex_exit(&ftable_lock);
1605 fn_lock = fnp->fn_lock;
1607 mutex_enter(&fn_lock->flk_lock);
1608 ASSERT(vp->v_stream == NULL);
1609 ASSERT(vp->v_count == 0);
1611 * if this is last reference to the lock, then we can
1612 * free everything up.
1614 if (--fn_lock->flk_ref == 0) {
1615 mutex_exit(&fn_lock->flk_lock);
1616 ASSERT(fnp->fn_open == 0);
1617 ASSERT(fnp->fn_dest->fn_open == 0);
1618 if (fnp->fn_mp) {
1619 freemsg(fnp->fn_mp);
1620 fnp->fn_mp = NULL;
1621 fnp->fn_count = 0;
1623 if (fnp->fn_pcredp != NULL) {
1624 crfree(fnp->fn_pcredp);
1625 fnp->fn_pcredp = NULL;
1627 if (fnp->fn_flag & ISPIPE) {
1628 fifonode_t *fn_dest = fnp->fn_dest;
1630 vp = FTOV(fn_dest);
1631 if (fn_dest->fn_mp) {
1632 freemsg(fn_dest->fn_mp);
1633 fn_dest->fn_mp = NULL;
1634 fn_dest->fn_count = 0;
1636 if (fn_dest->fn_pcredp != NULL) {
1637 crfree(fn_dest->fn_pcredp);
1638 fn_dest->fn_pcredp = NULL;
1640 kmem_cache_free(pipe_cache, (fifodata_t *)fn_lock);
1641 } else
1642 kmem_cache_free(fnode_cache, (fifodata_t *)fn_lock);
1643 } else {
1644 mutex_exit(&fn_lock->flk_lock);
1649 * If shadowing a vnode, apply the VOP_FID to it.
1650 * Otherwise, return EINVAL.
1653 fifo_fid(vnode_t *vp, fid_t *fidfnp, caller_context_t *ct)
1655 if (VTOF(vp)->fn_realvp)
1656 return (VOP_FID(VTOF(vp)->fn_realvp, fidfnp, ct));
1657 else
1658 return (EINVAL);
1662 * Lock a fifonode.
1664 /* ARGSUSED */
1666 fifo_rwlock(vnode_t *vp, int write_lock, caller_context_t *ctp)
1668 return (-1);
1672 * Unlock a fifonode.
1674 /* ARGSUSED */
1675 void
1676 fifo_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ctp)
1681 * Return error since seeks are not allowed on pipes.
1683 /*ARGSUSED*/
1685 fifo_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
1687 return (ESPIPE);
1691 * If there is a realvp associated with vp, return it.
1694 fifo_realvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
1696 vnode_t *rvp;
1698 if ((rvp = VTOF(vp)->fn_realvp) != NULL) {
1699 vp = rvp;
1700 if (VOP_REALVP(vp, &rvp, ct) == 0)
1701 vp = rvp;
1704 *vpp = vp;
1705 return (0);
1709 * Poll for interesting events on a stream pipe
1711 /* ARGSUSED */
1713 fifo_poll(vnode_t *vp, short events, int anyyet, short *reventsp,
1714 pollhead_t **phpp, caller_context_t *ct)
1716 fifonode_t *fnp, *fn_dest;
1717 fifolock_t *fn_lock;
1718 int retevents;
1719 struct stdata *stp;
1721 ASSERT(vp->v_stream != NULL);
1723 stp = vp->v_stream;
1724 retevents = 0;
1725 fnp = VTOF(vp);
1726 fn_dest = fnp->fn_dest;
1727 fn_lock = fnp->fn_lock;
1729 if (polllock(&stp->sd_pollist, &fn_lock->flk_lock) != 0) {
1730 *reventsp = POLLNVAL;
1731 return (0);
1735 * see if FIFO/pipe open
1737 if ((fnp->fn_flag & FIFOISOPEN) == 0) {
1738 if (((events & (POLLIN | POLLRDNORM | POLLPRI | POLLRDBAND)) &&
1739 fnp->fn_rcnt == 0) ||
1740 ((events & (POLLWRNORM | POLLWRBAND)) &&
1741 fnp->fn_wcnt == 0)) {
1742 mutex_exit(&fnp->fn_lock->flk_lock);
1743 *reventsp = POLLERR;
1744 return (0);
1749 * if not in fast mode, let the stream head take care of it
1751 if (!(fnp->fn_flag & FIFOFAST)) {
1752 mutex_exit(&fnp->fn_lock->flk_lock);
1753 goto stream_mode;
1757 * If this is a pipe.. check to see if the other
1758 * end is gone. If we are a fifo, check to see
1759 * if write end is gone.
1762 if ((fnp->fn_flag & ISPIPE) && (fn_dest->fn_open == 0)) {
1763 retevents = POLLHUP;
1764 } else if ((fnp->fn_flag & (FIFOCLOSE | ISPIPE)) == FIFOCLOSE &&
1765 (fn_dest->fn_wcnt == 0)) {
1767 * no writer at other end.
1768 * it was closed (versus yet to be opened)
1770 retevents = POLLHUP;
1771 } else if (events & (POLLWRNORM | POLLWRBAND)) {
1772 if (events & POLLWRNORM) {
1773 if (fn_dest->fn_count < Fifohiwat)
1774 retevents = POLLWRNORM;
1775 else
1776 fnp->fn_flag |= FIFOHIWATW;
1779 * This is always true for fast pipes
1780 * (Note: will go to STREAMS mode if band data is written)
1782 if (events & POLLWRBAND)
1783 retevents |= POLLWRBAND;
1785 if (events & (POLLIN | POLLRDNORM)) {
1786 if (fnp->fn_count)
1787 retevents |= (events & (POLLIN | POLLRDNORM));
1791 * if we happened to get something and we're not edge-triggered, return
1793 if ((*reventsp = (short)retevents) != 0 && !(events & POLLET)) {
1794 mutex_exit(&fnp->fn_lock->flk_lock);
1795 return (0);
1799 * If poll() has not found any events yet or we're edge-triggered, set
1800 * up event cell to wake up the poll if a requested event occurs on this
1801 * pipe/fifo.
1803 if (!anyyet) {
1804 if (events & POLLWRNORM)
1805 fnp->fn_flag |= FIFOPOLLW;
1806 if (events & (POLLIN | POLLRDNORM))
1807 fnp->fn_flag |= FIFOPOLLR;
1808 if (events & POLLRDBAND)
1809 fnp->fn_flag |= FIFOPOLLRBAND;
1811 * XXX Don't like exposing this from streams
1813 *phpp = &stp->sd_pollist;
1815 mutex_exit(&fnp->fn_lock->flk_lock);
1816 return (0);
1817 stream_mode:
1818 return (strpoll(stp, events, anyyet, reventsp, phpp));
1822 * POSIX pathconf() support.
1824 /* ARGSUSED */
1826 fifo_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
1827 caller_context_t *ct)
1829 ulong_t val;
1830 int error = 0;
1832 switch (cmd) {
1834 case _PC_LINK_MAX:
1835 val = MAXLINK;
1836 break;
1838 case _PC_MAX_CANON:
1839 val = MAX_CANON;
1840 break;
1842 case _PC_MAX_INPUT:
1843 val = MAX_INPUT;
1844 break;
1846 case _PC_NAME_MAX:
1847 error = EINVAL;
1848 break;
1850 case _PC_PATH_MAX:
1851 case _PC_SYMLINK_MAX:
1852 val = MAXPATHLEN;
1853 break;
1855 case _PC_PIPE_BUF:
1856 val = PIPE_BUF;
1857 break;
1859 case _PC_NO_TRUNC:
1860 if (vp->v_vfsp->vfs_flag & VFS_NOTRUNC)
1861 val = 1; /* NOTRUNC is enabled for vp */
1862 else
1863 val = (ulong_t)-1;
1864 break;
1866 case _PC_VDISABLE:
1867 val = _POSIX_VDISABLE;
1868 break;
1870 case _PC_CHOWN_RESTRICTED:
1871 if (rstchown)
1872 val = rstchown; /* chown restricted enabled */
1873 else
1874 val = (ulong_t)-1;
1875 break;
1877 case _PC_FILESIZEBITS:
1878 val = (ulong_t)-1;
1879 break;
1881 default:
1882 if (VTOF(vp)->fn_realvp)
1883 error = VOP_PATHCONF(VTOF(vp)->fn_realvp, cmd,
1884 &val, cr, ct);
1885 else
1886 error = EINVAL;
1887 break;
1890 if (error == 0)
1891 *valp = val;
1892 return (error);
1896 * If shadowing a vnode, apply VOP_SETSECATTR to it.
1897 * Otherwise, return NOSYS.
1900 fifo_setsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *crp,
1901 caller_context_t *ct)
1903 int error;
1906 * The acl(2) system call tries to grab the write lock on the
1907 * file when setting an ACL, but fifofs does not implement
1908 * VOP_RWLOCK or VOP_RWUNLOCK, so we do it here instead.
1910 if (VTOF(vp)->fn_realvp) {
1911 (void) VOP_RWLOCK(VTOF(vp)->fn_realvp, V_WRITELOCK_TRUE, ct);
1912 error = VOP_SETSECATTR(VTOF(vp)->fn_realvp, vsap, flag,
1913 crp, ct);
1914 VOP_RWUNLOCK(VTOF(vp)->fn_realvp, V_WRITELOCK_TRUE, ct);
1915 return (error);
1916 } else
1917 return (fs_nosys());
1921 * If shadowing a vnode, apply VOP_GETSECATTR to it. Otherwise, fabricate
1922 * an ACL from the permission bits that fifo_getattr() makes up.
1925 fifo_getsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *crp,
1926 caller_context_t *ct)
1928 if (VTOF(vp)->fn_realvp)
1929 return (VOP_GETSECATTR(VTOF(vp)->fn_realvp, vsap, flag,
1930 crp, ct));
1931 else
1932 return (fs_fab_acl(vp, vsap, flag, crp, ct));
1937 * Set the FIFOSTAYFAST flag so nobody can turn the fifo into stream mode.
1938 * If the flag is already set then wait until it is removed - releasing
1939 * the lock.
1940 * If the fifo switches into stream mode while we are waiting, return failure.
1942 static boolean_t
1943 fifo_stayfast_enter(fifonode_t *fnp)
1945 ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock));
1946 while (fnp->fn_flag & FIFOSTAYFAST) {
1947 fnp->fn_flag |= FIFOWAITMODE;
1948 cv_wait(&fnp->fn_wait_cv, &fnp->fn_lock->flk_lock);
1949 fnp->fn_flag &= ~FIFOWAITMODE;
1951 if (!(fnp->fn_flag & FIFOFAST))
1952 return (B_FALSE);
1954 fnp->fn_flag |= FIFOSTAYFAST;
1955 return (B_TRUE);
1959 * Unset the FIFOSTAYFAST flag and notify anybody waiting for this flag
1960 * to be removed:
1961 * - threads wanting to turn into stream mode waiting in fifo_fastoff(),
1962 * - other writers threads waiting in fifo_stayfast_enter().
1964 static void
1965 fifo_stayfast_exit(fifonode_t *fnp)
1967 fifonode_t *fn_dest = fnp->fn_dest;
1969 ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock));
1971 fnp->fn_flag &= ~FIFOSTAYFAST;
1973 if (fnp->fn_flag & FIFOWAITMODE)
1974 cv_broadcast(&fnp->fn_wait_cv);
1976 if ((fnp->fn_flag & ISPIPE) && (fn_dest->fn_flag & FIFOWAITMODE))
1977 cv_broadcast(&fn_dest->fn_wait_cv);