drop net-snmp dep
[unleashed.git] / kernel / fs / fifofs / fifovnops.c
blobcc6da464f5caa7ead25defbc0440b4325a136da2
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.
32 * Copyright (c) 2017 by Delphix. All rights reserved.
36 * FIFOFS file system vnode operations. This file system
37 * type supports STREAMS-based pipes and FIFOs.
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/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 const struct vnodeops fifo_vnodeops = {
120 .vnop_name = "fifofs",
121 .vop_open = fifo_open,
122 .vop_close = fifo_close,
123 .vop_read = fifo_read,
124 .vop_write = fifo_write,
125 .vop_ioctl = fifo_ioctl,
126 .vop_getattr = fifo_getattr,
127 .vop_setattr = fifo_setattr,
128 .vop_access = fifo_access,
129 .vop_create = fifo_create,
130 .vop_fsync = fifo_fsync,
131 .vop_inactive = fifo_inactive,
132 .vop_fid = fifo_fid,
133 .vop_rwlock = fifo_rwlock,
134 .vop_rwunlock = fifo_rwunlock,
135 .vop_seek = fifo_seek,
136 .vop_realvp = fifo_realvp,
137 .vop_poll = fifo_poll,
138 .vop_pathconf = fifo_pathconf,
139 .vop_dispose = fs_nodispose,
140 .vop_setsecattr = fifo_setsecattr,
141 .vop_getsecattr = fifo_getsecattr,
145 * Return the fifoinfo structure.
147 struct streamtab *
148 fifo_getinfo()
150 return (&fifoinfo);
154 * Open and stream a FIFO.
155 * If this is the first open of the file (FIFO is not streaming),
156 * initialize the fifonode and attach a stream to the vnode.
158 * Each end of a fifo must be synchronized with the other end.
159 * If not, the mated end may complete an open, I/O, close sequence
160 * before the end waiting in open ever wakes up.
161 * Note: namefs pipes come through this routine too.
164 fifo_open(vnode_t **vpp, int flag, cred_t *crp, caller_context_t *ct)
166 vnode_t *vp = *vpp;
167 fifonode_t *fnp = VTOF(vp);
168 fifolock_t *fn_lock = fnp->fn_lock;
169 int error;
171 ASSERT(vp->v_type == VFIFO);
172 ASSERT(vn_matchops(vp, &fifo_vnodeops));
174 mutex_enter(&fn_lock->flk_lock);
176 * If we are the first reader, wake up any writers that
177 * may be waiting around. wait for all of them to
178 * wake up before proceeding (i.e. fn_wsynccnt == 0)
180 if (flag & FREAD) {
181 fnp->fn_rcnt++; /* record reader present */
182 if (! (fnp->fn_flag & ISPIPE))
183 fnp->fn_rsynccnt++; /* record reader in open */
187 * If we are the first writer, wake up any readers that
188 * may be waiting around. wait for all of them to
189 * wake up before proceeding (i.e. fn_rsynccnt == 0)
191 if (flag & FWRITE) {
192 fnp->fn_wcnt++; /* record writer present */
193 if (! (fnp->fn_flag & ISPIPE))
194 fnp->fn_wsynccnt++; /* record writer in open */
197 * fifo_stropen will take care of twisting the queues on the first
198 * open. The 1 being passed in means twist the queues on the first
199 * open.
201 error = fifo_stropen(vpp, flag, crp, 1, 1);
203 * fifo_stropen() could have replaced vpp
204 * since fifo's are the only thing we need to sync up,
205 * everything else just returns;
206 * Note: don't need to hold lock since ISPIPE can't change
207 * and both old and new vp need to be pipes
209 ASSERT(MUTEX_HELD(&VTOF(*vpp)->fn_lock->flk_lock));
210 if (fnp->fn_flag & ISPIPE) {
211 ASSERT(VTOF(*vpp)->fn_flag & ISPIPE);
212 ASSERT(VTOF(*vpp)->fn_rsynccnt == 0);
213 ASSERT(VTOF(*vpp)->fn_rsynccnt == 0);
215 * XXX note: should probably hold locks, but
216 * These values should not be changing
218 ASSERT(fnp->fn_rsynccnt == 0);
219 ASSERT(fnp->fn_wsynccnt == 0);
220 mutex_exit(&VTOF(*vpp)->fn_lock->flk_lock);
221 return (error);
224 * vp can't change for FIFOS
226 ASSERT(vp == *vpp);
228 * If we are opening for read (or writer)
229 * indicate that the reader (or writer) is done with open
230 * if there is a writer (or reader) waiting for us, wake them up
231 * and indicate that at least 1 read (or write) open has occurred
232 * this is need in the event the read (or write) side closes
233 * before the writer (or reader) has a chance to wake up
234 * i.e. it sees that a reader (or writer) was once there
236 if (flag & FREAD) {
237 fnp->fn_rsynccnt--; /* reader done with open */
238 if (fnp->fn_flag & FIFOSYNC) {
240 * This indicates that a read open has occurred
241 * Only need to set if writer is actually asleep
242 * Flag will be consumed by writer.
244 fnp->fn_flag |= FIFOROCR;
245 cv_broadcast(&fnp->fn_wait_cv);
248 if (flag & FWRITE) {
249 fnp->fn_wsynccnt--; /* writer done with open */
250 if (fnp->fn_flag & FIFOSYNC) {
252 * This indicates that a write open has occurred
253 * Only need to set if reader is actually asleep
254 * Flag will be consumed by reader.
256 fnp->fn_flag |= FIFOWOCR;
257 cv_broadcast(&fnp->fn_wait_cv);
261 fnp->fn_flag &= ~FIFOSYNC;
264 * errors don't wait around.. just return
265 * Note: XXX other end will wake up and continue despite error.
266 * There is no defined semantic on the correct course of option
267 * so we do what we've done in the past
269 if (error != 0) {
270 mutex_exit(&fnp->fn_lock->flk_lock);
271 goto done;
273 ASSERT(fnp->fn_rsynccnt <= fnp->fn_rcnt);
274 ASSERT(fnp->fn_wsynccnt <= fnp->fn_wcnt);
276 * FIFOWOCR (or FIFOROCR) indicates that the writer (or reader)
277 * has woken us up and is done with open (this way, if the other
278 * end has made it to close, we don't block forever in open)
279 * fn_wnct == fn_wsynccnt (or fn_rcnt == fn_rsynccnt) indicates
280 * that no writer (or reader) has yet made it through open
281 * This has the side benefit of that the first
282 * reader (or writer) will wait until the other end finishes open
284 if (flag & FREAD) {
285 while ((fnp->fn_flag & FIFOWOCR) == 0 &&
286 fnp->fn_wcnt == fnp->fn_wsynccnt) {
287 if (flag & (FNDELAY|FNONBLOCK)) {
288 mutex_exit(&fnp->fn_lock->flk_lock);
289 goto done;
291 fnp->fn_insync++;
292 fnp->fn_flag |= FIFOSYNC;
293 if (!cv_wait_sig_swap(&fnp->fn_wait_cv,
294 &fnp->fn_lock->flk_lock)) {
296 * Last reader to wakeup clear writer
297 * Clear both writer and reader open
298 * occurred flag incase other end is O_RDWR
300 if (--fnp->fn_insync == 0 &&
301 fnp->fn_flag & FIFOWOCR) {
302 fnp->fn_flag &= ~(FIFOWOCR|FIFOROCR);
304 mutex_exit(&fnp->fn_lock->flk_lock);
305 (void) fifo_close(*vpp, flag, 1, 0, crp, ct);
306 error = EINTR;
307 goto done;
310 * Last reader to wakeup clear writer open occurred flag
311 * Clear both writer and reader open occurred flag
312 * incase other end is O_RDWR
314 if (--fnp->fn_insync == 0 &&
315 fnp->fn_flag & FIFOWOCR) {
316 fnp->fn_flag &= ~(FIFOWOCR|FIFOROCR);
317 break;
320 } else if (flag & FWRITE) {
321 while ((fnp->fn_flag & FIFOROCR) == 0 &&
322 fnp->fn_rcnt == fnp->fn_rsynccnt) {
323 if ((flag & (FNDELAY|FNONBLOCK)) && fnp->fn_rcnt == 0) {
324 mutex_exit(&fnp->fn_lock->flk_lock);
325 (void) fifo_close(*vpp, flag, 1, 0, crp, ct);
326 error = ENXIO;
327 goto done;
329 fnp->fn_flag |= FIFOSYNC;
330 fnp->fn_insync++;
331 if (!cv_wait_sig_swap(&fnp->fn_wait_cv,
332 &fnp->fn_lock->flk_lock)) {
334 * Last writer to wakeup clear
335 * Clear both writer and reader open
336 * occurred flag in case other end is O_RDWR
338 if (--fnp->fn_insync == 0 &&
339 (fnp->fn_flag & FIFOROCR) != 0) {
340 fnp->fn_flag &= ~(FIFOWOCR|FIFOROCR);
342 mutex_exit(&fnp->fn_lock->flk_lock);
343 (void) fifo_close(*vpp, flag, 1, 0, crp, ct);
344 error = EINTR;
345 goto done;
348 * Last writer to wakeup clear reader open occurred flag
349 * Clear both writer and reader open
350 * occurred flag in case other end is O_RDWR
352 if (--fnp->fn_insync == 0 &&
353 (fnp->fn_flag & FIFOROCR) != 0) {
354 fnp->fn_flag &= ~(FIFOWOCR|FIFOROCR);
355 break;
359 mutex_exit(&fn_lock->flk_lock);
360 done:
361 return (error);
365 * Close down a stream.
366 * Call cleanlocks() and strclean() on every close.
367 * For last close send hangup message and force
368 * the other end of a named pipe to be unmounted.
369 * Mount guarantees that the mounted end will only call fifo_close()
370 * with a count of 1 when the unmount occurs.
371 * This routine will close down one end of a pipe or FIFO
372 * and free the stream head via strclose()
374 /*ARGSUSED*/
376 fifo_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *crp,
377 caller_context_t *ct)
379 fifonode_t *fnp = VTOF(vp);
380 fifonode_t *fn_dest = fnp->fn_dest;
381 int error = 0;
382 fifolock_t *fn_lock = fnp->fn_lock;
383 queue_t *sd_wrq;
384 vnode_t *fn_dest_vp;
385 int senthang = 0;
387 ASSERT(vp->v_stream != NULL);
389 * clean locks and clear events.
391 (void) cleanlocks(vp, ttoproc(curthread)->p_pid, 0);
392 cleanshares(vp, ttoproc(curthread)->p_pid);
393 strclean(vp);
396 * If a file still has the pipe/FIFO open, return.
398 if (count > 1)
399 return (0);
402 sd_wrq = strvp2wq(vp);
403 mutex_enter(&fn_lock->flk_lock);
406 * wait for pending opens to finish up
407 * note: this also has the side effect of single threading closes
409 while (fn_lock->flk_ocsync)
410 cv_wait(&fn_lock->flk_wait_cv, &fn_lock->flk_lock);
412 fn_lock->flk_ocsync = 1;
414 if (flag & FREAD) {
415 fnp->fn_rcnt--;
418 * If we are last writer wake up sleeping readers
419 * (They'll figure out that there are no more writers
420 * and do the right thing)
421 * send hangup down stream so that stream head will do the
422 * right thing.
424 if (flag & FWRITE) {
425 if (--fnp->fn_wcnt == 0 && fn_dest->fn_rcnt > 0) {
426 if ((fn_dest->fn_flag & (FIFOFAST | FIFOWANTR)) ==
427 (FIFOFAST | FIFOWANTR)) {
429 * While we're at it, clear FIFOWANTW too
430 * Wake up any sleeping readers or
431 * writers.
433 fn_dest->fn_flag &= ~(FIFOWANTR | FIFOWANTW);
434 cv_broadcast(&fn_dest->fn_wait_cv);
437 * This is needed incase the other side
438 * was opened non-blocking. It is the
439 * only way we can tell that wcnt is 0 because
440 * of close instead of never having a writer
442 if (!(fnp->fn_flag & ISPIPE))
443 fnp->fn_flag |= FIFOCLOSE;
445 * Note: sending hangup effectively shuts down
446 * both reader and writer at other end.
448 (void) putnextctl_wait(sd_wrq, M_HANGUP);
449 senthang = 1;
454 * For FIFOs we need to indicate to stream head that last reader
455 * has gone away so that an error is generated
456 * Pipes just need to wake up the other end so that it can
457 * notice this end has gone away.
460 if (fnp->fn_rcnt == 0 && fn_dest->fn_wcnt > 0) {
461 if ((fn_dest->fn_flag & (FIFOFAST | FIFOWANTW)) ==
462 (FIFOFAST | FIFOWANTW)) {
464 * wake up any sleeping writers
466 fn_dest->fn_flag &= ~FIFOWANTW;
467 cv_broadcast(&fn_dest->fn_wait_cv);
472 * if there are still processes with this FIFO open
473 * clear open/close sync flag
474 * and just return;
476 if (--fnp->fn_open > 0) {
477 ASSERT((fnp->fn_rcnt + fnp->fn_wcnt) != 0);
478 fn_lock->flk_ocsync = 0;
479 cv_broadcast(&fn_lock->flk_wait_cv);
480 mutex_exit(&fn_lock->flk_lock);
481 return (0);
485 * Need to send HANGUP if other side is still open
486 * (fnp->fn_rcnt or fnp->fn_wcnt may not be zero (some thread
487 * on this end of the pipe may still be in fifo_open())
489 * Note: we can get here with fn_rcnt and fn_wcnt != 0 if some
490 * thread is blocked somewhere in the fifo_open() path prior to
491 * fifo_stropen() incrementing fn_open. This can occur for
492 * normal FIFOs as well as named pipes. fn_rcnt and
493 * fn_wcnt only indicate attempts to open. fn_open indicates
494 * successful opens. Partially opened FIFOs should proceed
495 * normally; i.e. they will appear to be new opens. Partially
496 * opened pipes will probably fail.
499 if (fn_dest->fn_open && senthang == 0)
500 (void) putnextctl_wait(sd_wrq, M_HANGUP);
504 * If this a pipe and this is the first end to close,
505 * then we have a bit of cleanup work to do.
506 * Mark both ends of pipe as closed.
507 * Wake up anybody blocked at the other end and for named pipes,
508 * Close down this end of the stream
509 * Allow other opens/closes to continue
510 * force an unmount of other end.
511 * Otherwise if this is last close,
512 * flush messages,
513 * close down the stream
514 * allow other opens/closes to continue
516 fnp->fn_flag &= ~FIFOISOPEN;
517 if ((fnp->fn_flag & ISPIPE) && !(fnp->fn_flag & FIFOCLOSE)) {
518 fnp->fn_flag |= FIFOCLOSE;
519 fn_dest->fn_flag |= FIFOCLOSE;
520 if (fnp->fn_flag & FIFOFAST)
521 fifo_fastflush(fnp);
522 if (vp->v_stream != NULL) {
523 mutex_exit(&fn_lock->flk_lock);
524 (void) strclose(vp, flag, crp);
525 mutex_enter(&fn_lock->flk_lock);
527 cv_broadcast(&fn_dest->fn_wait_cv);
529 * allow opens and closes to proceed
530 * Since this end is now closed down, any attempt
531 * to do anything with this end will fail
533 fn_lock->flk_ocsync = 0;
534 cv_broadcast(&fn_lock->flk_wait_cv);
535 fn_dest_vp = FTOV(fn_dest);
537 * if other end of pipe has been opened and it's
538 * a named pipe, unmount it
540 if (fn_dest_vp->v_stream &&
541 (fn_dest_vp->v_stream->sd_flag & STRMOUNT)) {
543 * We must hold the destination vnode because
544 * nm_unmountall() causes close to be called
545 * for the other end of named pipe. This
546 * could free the vnode before we are ready.
548 VN_HOLD(fn_dest_vp);
549 mutex_exit(&fn_lock->flk_lock);
550 error = nm_unmountall(fn_dest_vp, crp);
551 ASSERT(error == 0);
552 VN_RELE(fn_dest_vp);
553 } else {
554 ASSERT(vp->v_count >= 1);
555 mutex_exit(&fn_lock->flk_lock);
557 } else {
558 if (fnp->fn_flag & FIFOFAST)
559 fifo_fastflush(fnp);
560 #if DEBUG
561 fn_dest_vp = FTOV(fn_dest);
562 if (fn_dest_vp->v_stream)
563 ASSERT((fn_dest_vp->v_stream->sd_flag & STRMOUNT) == 0);
564 #endif
565 if (vp->v_stream != NULL) {
566 mutex_exit(&fn_lock->flk_lock);
567 (void) strclose(vp, flag, crp);
568 mutex_enter(&fn_lock->flk_lock);
570 fn_lock->flk_ocsync = 0;
571 cv_broadcast(&fn_lock->flk_wait_cv);
572 cv_broadcast(&fn_dest->fn_wait_cv);
573 mutex_exit(&fn_lock->flk_lock);
575 return (error);
579 * Read from a pipe or FIFO.
580 * return 0 if....
581 * (1) user read request is 0 or no stream
582 * (2) broken pipe with no data
583 * (3) write-only FIFO with no data
584 * (4) no data and FNDELAY flag is set.
585 * Otherwise return
586 * EAGAIN if FNONBLOCK is set and no data to read
587 * EINTR if signal received while waiting for data
589 * While there is no data to read....
590 * - if the NDELAY/NONBLOCK flag is set, return 0/EAGAIN.
591 * - wait for a write.
594 /*ARGSUSED*/
596 static int
597 fifo_read(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *crp,
598 caller_context_t *ct)
600 fifonode_t *fnp = VTOF(vp);
601 fifonode_t *fn_dest;
602 fifolock_t *fn_lock = fnp->fn_lock;
603 int error = 0;
604 mblk_t *bp;
606 ASSERT(vp->v_stream != NULL);
607 if (uiop->uio_resid == 0)
608 return (0);
610 mutex_enter(&fn_lock->flk_lock);
612 TRACE_2(TR_FAC_FIFO, TR_FIFOREAD_IN, "fifo_read in:%p fnp %p", vp, fnp);
614 if (! (fnp->fn_flag & FIFOFAST))
615 goto stream_mode;
617 fn_dest = fnp->fn_dest;
619 * Check for data on our input queue
622 while (fnp->fn_count == 0) {
624 * No data on first attempt and no writer, then EOF
626 if (fn_dest->fn_wcnt == 0 || fn_dest->fn_rcnt == 0) {
627 mutex_exit(&fn_lock->flk_lock);
628 return (0);
631 * no data found.. if non-blocking, return EAGAIN
632 * otherwise 0.
634 if (uiop->uio_fmode & (FNDELAY|FNONBLOCK)) {
635 mutex_exit(&fn_lock->flk_lock);
636 if (uiop->uio_fmode & FNONBLOCK)
637 return (EAGAIN);
638 return (0);
642 * Note: FIFOs can get here with FIFOCLOSE set if
643 * write side is in the middle of opeining after
644 * it once closed. Pipes better not have FIFOCLOSE set
646 ASSERT((fnp->fn_flag & (ISPIPE|FIFOCLOSE)) !=
647 (ISPIPE|FIFOCLOSE));
649 * wait for data
651 fnp->fn_flag |= FIFOWANTR;
653 TRACE_1(TR_FAC_FIFO, TR_FIFOREAD_WAIT, "fiforead wait: %p", vp);
655 if (!cv_wait_sig_swap(&fnp->fn_wait_cv,
656 &fn_lock->flk_lock)) {
657 error = EINTR;
658 goto done;
661 TRACE_1(TR_FAC_FIFO, TR_FIFOREAD_WAKE,
662 "fiforead awake: %p", vp);
665 * check to make sure we are still in fast mode
667 if (!(fnp->fn_flag & FIFOFAST))
668 goto stream_mode;
671 ASSERT(fnp->fn_mp != NULL);
673 /* For pipes copy should not bypass cache */
674 uiop->uio_extflg |= UIO_COPY_CACHED;
676 do {
677 int bpsize = MBLKL(fnp->fn_mp);
678 int uiosize = MIN(bpsize, uiop->uio_resid);
680 error = uiomove(fnp->fn_mp->b_rptr, uiosize, UIO_READ, uiop);
681 if (error != 0)
682 break;
684 fnp->fn_count -= uiosize;
686 if (bpsize <= uiosize) {
687 bp = fnp->fn_mp;
688 fnp->fn_mp = fnp->fn_mp->b_cont;
689 freeb(bp);
691 if (uiop->uio_resid == 0)
692 break;
694 while (fnp->fn_mp == NULL && fn_dest->fn_wwaitcnt > 0) {
695 ASSERT(fnp->fn_count == 0);
697 if (uiop->uio_fmode & (FNDELAY|FNONBLOCK))
698 goto trywake;
701 * We've consumed all available data but there
702 * are threads waiting to write more, let them
703 * proceed before bailing.
706 fnp->fn_flag |= FIFOWANTR;
707 fifo_wakewriter(fn_dest, fn_lock);
709 if (!cv_wait_sig(&fnp->fn_wait_cv,
710 &fn_lock->flk_lock))
711 goto trywake;
713 if (!(fnp->fn_flag & FIFOFAST))
714 goto stream_mode;
716 } else {
717 fnp->fn_mp->b_rptr += uiosize;
718 ASSERT(uiop->uio_resid == 0);
720 } while (uiop->uio_resid != 0 && fnp->fn_mp != NULL);
722 trywake:
723 ASSERT(msgdsize(fnp->fn_mp) == fnp->fn_count);
726 * wake up any blocked writers, processes
727 * sleeping on POLLWRNORM, or processes waiting for SIGPOLL
728 * Note: checking for fn_count < Fifohiwat emulates
729 * STREAMS functionality when low water mark is 0
731 if (fn_dest->fn_flag & (FIFOWANTW | FIFOHIWATW) &&
732 fnp->fn_count < Fifohiwat) {
733 fifo_wakewriter(fn_dest, fn_lock);
735 goto done;
738 * FIFO is in streams mode.. let the stream head handle it
740 stream_mode:
742 mutex_exit(&fn_lock->flk_lock);
743 TRACE_1(TR_FAC_FIFO,
744 TR_FIFOREAD_STREAM, "fifo_read stream_mode:%p", vp);
746 error = strread(vp, uiop, crp);
748 mutex_enter(&fn_lock->flk_lock);
750 done:
752 * vnode update access time
754 if (error == 0) {
755 time_t now = gethrestime_sec();
757 if (fnp->fn_flag & ISPIPE)
758 fnp->fn_dest->fn_atime = now;
759 fnp->fn_atime = now;
761 TRACE_2(TR_FAC_FIFO, TR_FIFOREAD_OUT,
762 "fifo_read out:%p error %d", vp, error);
763 mutex_exit(&fn_lock->flk_lock);
764 return (error);
768 * send SIGPIPE and return EPIPE if ...
769 * (1) broken pipe (essentially, reader is gone)
770 * (2) FIFO is not open for reading
771 * return 0 if...
772 * (1) no stream
773 * (2) user write request is for 0 bytes and SW_SNDZERO is not set
774 * Note: SW_SNDZERO can't be set in fast mode
775 * While the stream is flow controlled....
776 * - if the NDELAY/NONBLOCK flag is set, return 0/EAGAIN.
777 * - unlock the fifonode and sleep waiting for a reader.
778 * - if a pipe and it has a mate, sleep waiting for its mate
779 * to read.
781 /*ARGSUSED*/
782 static int
783 fifo_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *crp,
784 caller_context_t *ct)
786 struct fifonode *fnp, *fn_dest;
787 fifolock_t *fn_lock;
788 struct stdata *stp;
789 int error = 0;
790 int write_size;
791 int size;
792 int fmode;
793 mblk_t *bp;
794 boolean_t hotread;
796 ASSERT(vp->v_stream);
797 uiop->uio_loffset = 0;
798 stp = vp->v_stream;
801 * remember original number of bytes requested. Used to determine if
802 * we actually have written anything at all
804 write_size = uiop->uio_resid;
807 * only send zero-length messages if SW_SNDZERO is set
808 * Note: we will be in streams mode if SW_SNDZERO is set
809 * XXX this streams interface should not be exposed
811 if ((write_size == 0) && !(stp->sd_wput_opt & SW_SNDZERO))
812 return (0);
814 fnp = VTOF(vp);
815 fn_lock = fnp->fn_lock;
816 fn_dest = fnp->fn_dest;
818 mutex_enter(&fn_lock->flk_lock);
820 TRACE_3(TR_FAC_FIFO, TR_FIFOWRITE_IN,
821 "fifo_write in:%p fnp %p size %d", vp, fnp, write_size);
824 * oops, no readers, error
826 if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
827 goto epipe;
831 * if we are not in fast mode, let streams handle it
833 if (!(fnp->fn_flag & FIFOFAST))
834 goto stream_mode;
836 fmode = uiop->uio_fmode & (FNDELAY|FNONBLOCK);
838 /* For pipes copy should not bypass cache */
839 uiop->uio_extflg |= UIO_COPY_CACHED;
841 do {
843 * check to make sure we are not over high water mark
845 while (fn_dest->fn_count >= Fifohiwat) {
847 * Indicate that we have gone over high
848 * water mark
851 * if non-blocking, return
852 * only happens first time through loop
854 if (fmode) {
855 fnp->fn_flag |= FIFOHIWATW;
856 if (uiop->uio_resid == write_size) {
857 mutex_exit(&fn_lock->flk_lock);
858 if (fmode & FNDELAY)
859 return (0);
860 else
861 return (EAGAIN);
863 goto done;
867 * wait for things to drain
869 fnp->fn_flag |= FIFOWANTW;
870 fnp->fn_wwaitcnt++;
871 TRACE_1(TR_FAC_FIFO, TR_FIFOWRITE_WAIT,
872 "fifo_write wait: %p", vp);
873 if (!cv_wait_sig_swap(&fnp->fn_wait_cv,
874 &fn_lock->flk_lock)) {
875 error = EINTR;
876 fnp->fn_wwaitcnt--;
877 fifo_wakereader(fn_dest, fn_lock);
878 goto done;
880 fnp->fn_wwaitcnt--;
882 TRACE_1(TR_FAC_FIFO, TR_FIFOWRITE_WAKE,
883 "fifo_write wake: %p", vp);
886 * check to make sure we're still in fast mode
888 if (!(fnp->fn_flag & FIFOFAST))
889 goto stream_mode;
892 * make sure readers didn't go away
894 if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
895 goto epipe;
899 * If the write will put us over the high water mark,
900 * then we must break the message up into PIPE_BUF
901 * chunks to stay compliant with STREAMS
903 if (uiop->uio_resid + fn_dest->fn_count > Fifohiwat)
904 size = MIN(uiop->uio_resid, PIPE_BUF);
905 else
906 size = uiop->uio_resid;
909 * We don't need to hold flk_lock across the allocb() and
910 * uiomove(). However, on a multiprocessor machine where both
911 * the reader and writer thread are on cpu's, we must be
912 * careful to only drop the lock if there's data to be read.
913 * This forces threads entering fifo_read() to spin or block
914 * on flk_lock, rather than acquiring flk_lock only to
915 * discover there's no data to read and being forced to go
916 * back to sleep, only to be woken up microseconds later by
917 * this writer thread.
919 hotread = fn_dest->fn_count > 0;
920 if (hotread) {
921 if (!fifo_stayfast_enter(fnp))
922 goto stream_mode;
923 mutex_exit(&fn_lock->flk_lock);
926 ASSERT(size != 0);
928 * Align the mblk with the user data so that
929 * copying in the data can take advantage of
930 * the double word alignment
932 if ((bp = allocb(size + 8, BPRI_MED)) == NULL) {
933 if (!hotread)
934 mutex_exit(&fn_lock->flk_lock);
936 error = strwaitbuf(size, BPRI_MED);
938 mutex_enter(&fn_lock->flk_lock);
940 if (hotread) {
942 * As we dropped the mutex for a moment, we
943 * need to wake up any thread waiting to be
944 * allowed to go from fast mode to stream mode.
946 fifo_stayfast_exit(fnp);
948 if (error != 0) {
949 goto done;
952 * check to make sure we're still in fast mode
954 if (!(fnp->fn_flag & FIFOFAST))
955 goto stream_mode;
958 * make sure readers didn't go away
960 if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
961 goto epipe;
964 * some other thread could have gotten in
965 * need to go back and check hi water mark
967 continue;
969 bp->b_rptr += ((uintptr_t)uiop->uio_iov->iov_base & 0x7);
970 bp->b_wptr = bp->b_rptr + size;
971 error = uiomove((caddr_t)bp->b_rptr, size, UIO_WRITE, uiop);
972 if (hotread) {
973 mutex_enter(&fn_lock->flk_lock);
975 * As we dropped the mutex for a moment, we need to:
976 * - wake up any thread waiting to be allowed to go
977 * from fast mode to stream mode,
978 * - make sure readers didn't go away.
980 fifo_stayfast_exit(fnp);
981 if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
982 freeb(bp);
983 goto epipe;
987 if (error != 0) {
988 freeb(bp);
989 goto done;
992 fn_dest->fn_count += size;
993 if (fn_dest->fn_mp != NULL) {
994 fn_dest->fn_tail->b_cont = bp;
995 fn_dest->fn_tail = bp;
996 } else {
997 fn_dest->fn_mp = fn_dest->fn_tail = bp;
999 * This is the first bit of data; wake up any sleeping
1000 * readers, processes blocked in poll, and those
1001 * expecting a SIGPOLL.
1003 fifo_wakereader(fn_dest, fn_lock);
1005 } while (uiop->uio_resid != 0);
1007 goto done;
1009 stream_mode:
1011 * streams mode
1012 * let the stream head handle the write
1014 ASSERT(MUTEX_HELD(&fn_lock->flk_lock));
1016 mutex_exit(&fn_lock->flk_lock);
1017 TRACE_1(TR_FAC_FIFO,
1018 TR_FIFOWRITE_STREAM, "fifo_write stream_mode:%p", vp);
1020 error = strwrite(vp, uiop, crp);
1022 mutex_enter(&fn_lock->flk_lock);
1024 done:
1026 * update vnode modification and change times
1027 * make sure there were no errors and some data was transferred
1029 if (error == 0 && write_size != uiop->uio_resid) {
1030 time_t now = gethrestime_sec();
1032 if (fnp->fn_flag & ISPIPE) {
1033 fn_dest->fn_mtime = fn_dest->fn_ctime = now;
1035 fnp->fn_mtime = fnp->fn_ctime = now;
1036 } else if (fn_dest->fn_rcnt == 0 || fn_dest->fn_wcnt == 0) {
1037 goto epipe;
1039 TRACE_3(TR_FAC_FIFO, TR_FIFOWRITE_OUT,
1040 "fifo_write out: vp %p error %d fnp %p", vp, error, fnp);
1041 mutex_exit(&fn_lock->flk_lock);
1042 return (error);
1043 epipe:
1044 error = EPIPE;
1045 TRACE_3(TR_FAC_FIFO, TR_FIFOWRITE_OUT,
1046 "fifo_write out: vp %p error %d fnp %p", vp, error, fnp);
1047 mutex_exit(&fn_lock->flk_lock);
1048 tsignal(curthread, SIGPIPE);
1049 return (error);
1052 /*ARGSUSED6*/
1053 static int
1054 fifo_ioctl(vnode_t *vp, int cmd, intptr_t arg, int mode, cred_t *cr,
1055 int *rvalp, caller_context_t *ct)
1058 * Just a quick check
1059 * Once we go to streams mode we don't ever revert back
1060 * So we do this quick check so as not to incur the overhead
1061 * associated with acquiring the lock
1063 return ((VTOF(vp)->fn_flag & FIFOFAST) ?
1064 fifo_fastioctl(vp, cmd, arg, mode, cr, rvalp) :
1065 fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1068 static inline int
1069 fifo_ioctl_getpeercred(fifonode_t *fnp, intptr_t arg, int mode)
1071 k_peercred_t *kp = (k_peercred_t *)arg;
1073 if (mode == FKIOCTL && fnp->fn_pcredp != NULL) {
1074 crhold(fnp->fn_pcredp);
1075 kp->pc_cr = fnp->fn_pcredp;
1076 kp->pc_cpid = fnp->fn_cpid;
1077 return (0);
1078 } else {
1079 return (ENOTSUP);
1083 static int
1084 fifo_fastioctl(vnode_t *vp, int cmd, intptr_t arg, int mode, cred_t *cr,
1085 int *rvalp)
1087 fifonode_t *fnp = VTOF(vp);
1088 fifonode_t *fn_dest;
1089 int error = 0;
1090 fifolock_t *fn_lock = fnp->fn_lock;
1091 int cnt;
1094 * tty operations not allowed
1096 if (((cmd & IOCTYPE) == LDIOC) ||
1097 ((cmd & IOCTYPE) == tIOC) ||
1098 ((cmd & IOCTYPE) == TIOC)) {
1099 return (EINVAL);
1102 mutex_enter(&fn_lock->flk_lock);
1104 if (!(fnp->fn_flag & FIFOFAST)) {
1105 goto stream_mode;
1108 switch (cmd) {
1111 * Things we can't handle
1112 * These will switch us to streams mode.
1114 default:
1115 case I_STR:
1116 case I_SRDOPT:
1117 case I_PUSH:
1118 case I_FDINSERT:
1119 case I_SENDFD:
1120 case I_RECVFD:
1121 case I_E_RECVFD:
1122 case I_ATMARK:
1123 case I_CKBAND:
1124 case I_GETBAND:
1125 case I_SWROPT:
1126 goto turn_fastoff;
1129 * Things that don't do damage
1130 * These things don't adjust the state of the
1131 * stream head (i_setcltime does, but we don't care)
1133 case I_FIND:
1134 case I_GETSIG:
1135 case FIONBIO:
1136 case FIOASYNC:
1137 case I_GRDOPT: /* probably should not get this, but no harm */
1138 case I_GWROPT:
1139 case I_LIST:
1140 case I_SETCLTIME:
1141 case I_GETCLTIME:
1142 mutex_exit(&fn_lock->flk_lock);
1143 return (strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp));
1145 case I_CANPUT:
1147 * We can only handle normal band canputs.
1148 * XXX : We could just always go to stream mode; after all
1149 * canput is a streams semantics type thing
1151 if (arg != 0) {
1152 goto turn_fastoff;
1154 *rvalp = (fnp->fn_dest->fn_count < Fifohiwat) ? 1 : 0;
1155 mutex_exit(&fn_lock->flk_lock);
1156 return (0);
1158 case I_NREAD:
1160 * This may seem a bit silly for non-streams semantics,
1161 * (After all, if they really want a message, they'll
1162 * probably use getmsg() anyway). but it doesn't hurt
1164 error = copyout((caddr_t)&fnp->fn_count, (caddr_t)arg,
1165 sizeof (cnt));
1166 if (error == 0) {
1167 *rvalp = (fnp->fn_count == 0) ? 0 : 1;
1169 break;
1171 case FIORDCHK:
1172 *rvalp = fnp->fn_count;
1173 break;
1175 case I_PEEK:
1177 STRUCT_DECL(strpeek, strpeek);
1178 struct uio uio;
1179 struct iovec iov;
1180 int count;
1181 mblk_t *bp;
1182 int len;
1184 STRUCT_INIT(strpeek, mode);
1186 if (fnp->fn_count == 0) {
1187 *rvalp = 0;
1188 break;
1191 error = copyin((caddr_t)arg, STRUCT_BUF(strpeek),
1192 STRUCT_SIZE(strpeek));
1193 if (error)
1194 break;
1197 * can't have any high priority message when in fast mode
1199 if (STRUCT_FGET(strpeek, flags) & RS_HIPRI) {
1200 *rvalp = 0;
1201 break;
1204 len = STRUCT_FGET(strpeek, databuf.maxlen);
1205 if (len <= 0) {
1206 STRUCT_FSET(strpeek, databuf.len, len);
1207 } else {
1208 iov.iov_base = STRUCT_FGETP(strpeek, databuf.buf);
1209 iov.iov_len = len;
1210 uio.uio_iov = &iov;
1211 uio.uio_iovcnt = 1;
1212 uio.uio_loffset = 0;
1213 uio.uio_segflg = UIO_USERSPACE;
1214 uio.uio_fmode = 0;
1215 /* For pipes copy should not bypass cache */
1216 uio.uio_extflg = UIO_COPY_CACHED;
1217 uio.uio_resid = iov.iov_len;
1218 count = fnp->fn_count;
1219 bp = fnp->fn_mp;
1220 while (count > 0 && uio.uio_resid) {
1221 cnt = MIN(uio.uio_resid, MBLKL(bp));
1222 if ((error = uiomove((char *)bp->b_rptr, cnt,
1223 UIO_READ, &uio)) != 0) {
1224 break;
1226 count -= cnt;
1227 bp = bp->b_cont;
1229 STRUCT_FSET(strpeek, databuf.len, len - uio.uio_resid);
1231 STRUCT_FSET(strpeek, flags, 0);
1232 STRUCT_FSET(strpeek, ctlbuf.len, -1);
1234 error = copyout(STRUCT_BUF(strpeek), (caddr_t)arg,
1235 STRUCT_SIZE(strpeek));
1236 if (error == 0 && len >= 0)
1237 *rvalp = 1;
1238 break;
1241 case FIONREAD:
1243 * let user know total number of bytes in message queue
1245 error = copyout((caddr_t)&fnp->fn_count, (caddr_t)arg,
1246 sizeof (fnp->fn_count));
1247 if (error == 0)
1248 *rvalp = 0;
1249 break;
1251 case I_SETSIG:
1253 * let streams set up the signal masking for us
1254 * we just check to see if it's set
1255 * XXX : this interface should not be visible
1256 * i.e. STREAM's framework is exposed.
1258 error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
1259 if (vp->v_stream->sd_sigflags & (S_INPUT|S_RDNORM|S_WRNORM))
1260 fnp->fn_flag |= FIFOSETSIG;
1261 else
1262 fnp->fn_flag &= ~FIFOSETSIG;
1263 break;
1265 case I_FLUSH:
1267 * flush them message queues
1269 if (arg & ~FLUSHRW) {
1270 error = EINVAL;
1271 break;
1273 if (arg & FLUSHR) {
1274 fifo_fastflush(fnp);
1276 fn_dest = fnp->fn_dest;
1277 if ((arg & FLUSHW)) {
1278 fifo_fastflush(fn_dest);
1281 * wake up any sleeping readers or writers
1282 * (waking readers probably doesn't make sense, but it
1283 * doesn't hurt; i.e. we just got rid of all the data
1284 * what's to read ?)
1286 if (fn_dest->fn_flag & (FIFOWANTW | FIFOWANTR)) {
1287 fn_dest->fn_flag &= ~(FIFOWANTW | FIFOWANTR);
1288 cv_broadcast(&fn_dest->fn_wait_cv);
1290 *rvalp = 0;
1291 break;
1294 * Since no band data can ever get on a fifo in fast mode
1295 * just return 0.
1297 case I_FLUSHBAND:
1298 error = 0;
1299 *rvalp = 0;
1300 break;
1302 case _I_GETPEERCRED:
1303 error = fifo_ioctl_getpeercred(fnp, arg, mode);
1304 break;
1307 * invalid calls for stream head or fifos
1310 case I_POP: /* shouldn't happen */
1311 case I_LOOK:
1312 case I_LINK:
1313 case I_PLINK:
1314 case I_UNLINK:
1315 case I_PUNLINK:
1318 * more invalid tty type of ioctls
1321 case SRIOCSREDIR:
1322 case SRIOCISREDIR:
1323 error = EINVAL;
1324 break;
1327 mutex_exit(&fn_lock->flk_lock);
1328 return (error);
1330 turn_fastoff:
1331 fifo_fastoff(fnp);
1333 stream_mode:
1335 * streams mode
1337 mutex_exit(&fn_lock->flk_lock);
1338 return (fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1343 * FIFO is in STREAMS mode; STREAMS framework does most of the work.
1345 static int
1346 fifo_strioctl(vnode_t *vp, int cmd, intptr_t arg, int mode, cred_t *cr,
1347 int *rvalp)
1349 fifonode_t *fnp = VTOF(vp);
1350 int error;
1351 fifolock_t *fn_lock;
1353 if (cmd == _I_GETPEERCRED)
1354 return (fifo_ioctl_getpeercred(fnp, arg, mode));
1356 error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
1358 switch (cmd) {
1360 * The FIFOSEND flag is set to inform other processes that a file
1361 * descriptor is pending at the stream head of this pipe.
1362 * The flag is cleared and the sending process is awoken when
1363 * this process has completed receiving the file descriptor.
1364 * XXX This could become out of sync if the process does I_SENDFDs
1365 * and opens on connld attached to the same pipe.
1367 case I_RECVFD:
1368 case I_E_RECVFD:
1369 if (error == 0) {
1370 fn_lock = fnp->fn_lock;
1371 mutex_enter(&fn_lock->flk_lock);
1372 if (fnp->fn_flag & FIFOSEND) {
1373 fnp->fn_flag &= ~FIFOSEND;
1374 cv_broadcast(&fnp->fn_dest->fn_wait_cv);
1376 mutex_exit(&fn_lock->flk_lock);
1378 break;
1379 default:
1380 break;
1383 return (error);
1387 * If shadowing a vnode (FIFOs), apply the fop_getattr to the shadowed
1388 * vnode to Obtain the node information. If not shadowing (pipes), obtain
1389 * the node information from the credentials structure.
1392 fifo_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *crp,
1393 caller_context_t *ct)
1395 int error = 0;
1396 fifonode_t *fnp = VTOF(vp);
1397 queue_t *qp;
1398 qband_t *bandp;
1399 fifolock_t *fn_lock = fnp->fn_lock;
1401 if (fnp->fn_realvp) {
1403 * for FIFOs or mounted pipes
1405 if (error = fop_getattr(fnp->fn_realvp, vap, flags, crp, ct))
1406 return (error);
1407 mutex_enter(&fn_lock->flk_lock);
1408 /* set current times from fnode, even if older than vnode */
1409 vap->va_atime.tv_sec = fnp->fn_atime;
1410 vap->va_atime.tv_nsec = 0;
1411 vap->va_mtime.tv_sec = fnp->fn_mtime;
1412 vap->va_mtime.tv_nsec = 0;
1413 vap->va_ctime.tv_sec = fnp->fn_ctime;
1414 vap->va_ctime.tv_nsec = 0;
1415 } else {
1417 * for non-attached/ordinary pipes
1419 vap->va_mode = 0;
1420 mutex_enter(&fn_lock->flk_lock);
1421 vap->va_atime.tv_sec = fnp->fn_atime;
1422 vap->va_atime.tv_nsec = 0;
1423 vap->va_mtime.tv_sec = fnp->fn_mtime;
1424 vap->va_mtime.tv_nsec = 0;
1425 vap->va_ctime.tv_sec = fnp->fn_ctime;
1426 vap->va_ctime.tv_nsec = 0;
1427 vap->va_uid = crgetuid(crp);
1428 vap->va_gid = crgetgid(crp);
1429 vap->va_nlink = 0;
1430 vap->va_fsid = fifodev;
1431 vap->va_nodeid = (ino64_t)fnp->fn_ino;
1432 vap->va_rdev = 0;
1434 vap->va_type = VFIFO;
1435 vap->va_blksize = PIPE_BUF;
1437 * Size is number of un-read bytes at the stream head and
1438 * nblocks is the unread bytes expressed in blocks.
1440 if (vp->v_stream && (fnp->fn_flag & FIFOISOPEN)) {
1441 if ((fnp->fn_flag & FIFOFAST)) {
1442 vap->va_size = (uoff_t)fnp->fn_count;
1443 } else {
1444 qp = RD((strvp2wq(vp)));
1445 vap->va_size = (uoff_t)qp->q_count;
1446 if (qp->q_nband != 0) {
1447 mutex_enter(QLOCK(qp));
1448 for (bandp = qp->q_bandp; bandp;
1449 bandp = bandp->qb_next)
1450 vap->va_size += bandp->qb_count;
1451 mutex_exit(QLOCK(qp));
1454 vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size);
1455 } else {
1456 vap->va_size = 0;
1457 vap->va_nblocks = (fsblkcnt64_t)0;
1459 mutex_exit(&fn_lock->flk_lock);
1460 vap->va_seq = 0;
1461 return (0);
1465 * If shadowing a vnode, apply the fop_setattr to it, and to the fnode.
1466 * Otherwise, set the time and return 0.
1469 fifo_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *crp,
1470 caller_context_t *ctp)
1472 fifonode_t *fnp = VTOF(vp);
1473 int error = 0;
1474 fifolock_t *fn_lock;
1476 if (fnp->fn_realvp)
1477 error = fop_setattr(fnp->fn_realvp, vap, flags, crp, ctp);
1478 if (error == 0) {
1479 fn_lock = fnp->fn_lock;
1480 mutex_enter(&fn_lock->flk_lock);
1481 if (vap->va_mask & VATTR_ATIME)
1482 fnp->fn_atime = vap->va_atime.tv_sec;
1483 if (vap->va_mask & VATTR_MTIME)
1484 fnp->fn_mtime = vap->va_mtime.tv_sec;
1485 fnp->fn_ctime = gethrestime_sec();
1486 mutex_exit(&fn_lock->flk_lock);
1488 return (error);
1492 * If shadowing a vnode, apply fop_access to it.
1493 * Otherwise, return 0 (allow all access).
1496 fifo_access(vnode_t *vp, int mode, int flags, cred_t *crp, caller_context_t *ct)
1498 if (VTOF(vp)->fn_realvp)
1499 return (fop_access(VTOF(vp)->fn_realvp, mode, flags, crp, ct));
1500 else
1501 return (0);
1505 * This can be called if creat or an open with O_CREAT is done on the root
1506 * of a lofs mount where the mounted entity is a fifo.
1508 /*ARGSUSED*/
1509 static int
1510 fifo_create(struct vnode *dvp, char *name, vattr_t *vap, enum vcexcl excl,
1511 int mode, struct vnode **vpp, struct cred *cr, int flag,
1512 caller_context_t *ct, vsecattr_t *vsecp)
1514 int error;
1516 ASSERT(dvp && (dvp->v_flag & VROOT) && *name == '\0');
1517 if (excl == NONEXCL) {
1518 if (mode && (error = fifo_access(dvp, mode, 0, cr, ct)))
1519 return (error);
1520 VN_HOLD(dvp);
1521 return (0);
1523 return (EEXIST);
1527 * If shadowing a vnode, apply the fop_fsync to it.
1528 * Otherwise, return 0.
1531 fifo_fsync(vnode_t *vp, int syncflag, cred_t *crp, caller_context_t *ct)
1533 fifonode_t *fnp = VTOF(vp);
1534 vattr_t va;
1536 if (fnp->fn_realvp == NULL)
1537 return (0);
1539 bzero((caddr_t)&va, sizeof (va));
1540 va.va_mask = VATTR_MTIME | VATTR_ATIME;
1541 if (fop_getattr(fnp->fn_realvp, &va, 0, crp, ct) == 0) {
1542 va.va_mask = 0;
1543 if (fnp->fn_mtime > va.va_mtime.tv_sec) {
1544 va.va_mtime.tv_sec = fnp->fn_mtime;
1545 va.va_mask = VATTR_MTIME;
1547 if (fnp->fn_atime > va.va_atime.tv_sec) {
1548 va.va_atime.tv_sec = fnp->fn_atime;
1549 va.va_mask |= VATTR_ATIME;
1551 if (va.va_mask != 0)
1552 (void) fop_setattr(fnp->fn_realvp, &va, 0, crp, ct);
1554 return (fop_fsync(fnp->fn_realvp, syncflag, crp, ct));
1558 * Called when the upper level no longer holds references to the
1559 * vnode. Sync the file system and free the fifonode.
1561 void
1562 fifo_inactive(vnode_t *vp, cred_t *crp, caller_context_t *ct)
1564 fifonode_t *fnp;
1565 fifolock_t *fn_lock;
1567 mutex_enter(&ftable_lock);
1568 mutex_enter(&vp->v_lock);
1569 ASSERT(vp->v_count >= 1);
1570 VN_RELE_LOCKED(vp);
1571 if (vp->v_count != 0) {
1573 * Somebody accessed the fifo before we got a chance to
1574 * remove it. They will remove it when they do a vn_rele.
1576 mutex_exit(&vp->v_lock);
1577 mutex_exit(&ftable_lock);
1578 return;
1580 mutex_exit(&vp->v_lock);
1582 fnp = VTOF(vp);
1585 * remove fifo from fifo list so that no other process
1586 * can grab it.
1587 * Drop the reference count on the fifo node's
1588 * underlying vfs.
1590 if (fnp->fn_realvp) {
1591 (void) fiforemove(fnp);
1592 mutex_exit(&ftable_lock);
1593 (void) fifo_fsync(vp, FSYNC, crp, ct);
1594 VN_RELE(fnp->fn_realvp);
1595 VFS_RELE(vp->v_vfsp);
1596 vp->v_vfsp = NULL;
1597 } else
1598 mutex_exit(&ftable_lock);
1600 fn_lock = fnp->fn_lock;
1602 mutex_enter(&fn_lock->flk_lock);
1603 ASSERT(vp->v_stream == NULL);
1604 ASSERT(vp->v_count == 0);
1606 * if this is last reference to the lock, then we can
1607 * free everything up.
1609 if (--fn_lock->flk_ref == 0) {
1610 mutex_exit(&fn_lock->flk_lock);
1611 ASSERT(fnp->fn_open == 0);
1612 ASSERT(fnp->fn_dest->fn_open == 0);
1613 if (fnp->fn_mp) {
1614 freemsg(fnp->fn_mp);
1615 fnp->fn_mp = NULL;
1616 fnp->fn_count = 0;
1618 if (fnp->fn_pcredp != NULL) {
1619 crfree(fnp->fn_pcredp);
1620 fnp->fn_pcredp = NULL;
1622 if (fnp->fn_flag & ISPIPE) {
1623 fifonode_t *fn_dest = fnp->fn_dest;
1625 vp = FTOV(fn_dest);
1626 if (fn_dest->fn_mp) {
1627 freemsg(fn_dest->fn_mp);
1628 fn_dest->fn_mp = NULL;
1629 fn_dest->fn_count = 0;
1631 if (fn_dest->fn_pcredp != NULL) {
1632 crfree(fn_dest->fn_pcredp);
1633 fn_dest->fn_pcredp = NULL;
1635 kmem_cache_free(pipe_cache, (fifodata_t *)fn_lock);
1636 } else
1637 kmem_cache_free(fnode_cache, (fifodata_t *)fn_lock);
1638 } else {
1639 mutex_exit(&fn_lock->flk_lock);
1644 * If shadowing a vnode, apply the fop_fid to it.
1645 * Otherwise, return EINVAL.
1648 fifo_fid(vnode_t *vp, fid_t *fidfnp, caller_context_t *ct)
1650 if (VTOF(vp)->fn_realvp)
1651 return (fop_fid(VTOF(vp)->fn_realvp, fidfnp, ct));
1652 else
1653 return (EINVAL);
1657 * Lock a fifonode.
1659 /* ARGSUSED */
1661 fifo_rwlock(vnode_t *vp, int write_lock, caller_context_t *ctp)
1663 return (-1);
1667 * Unlock a fifonode.
1669 /* ARGSUSED */
1670 void
1671 fifo_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ctp)
1676 * Return error since seeks are not allowed on pipes.
1678 /*ARGSUSED*/
1680 fifo_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
1682 return (ESPIPE);
1686 * If there is a realvp associated with vp, return it.
1689 fifo_realvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
1691 vnode_t *rvp;
1693 if ((rvp = VTOF(vp)->fn_realvp) != NULL) {
1694 vp = rvp;
1695 if (fop_realvp(vp, &rvp, ct) == 0)
1696 vp = rvp;
1699 *vpp = vp;
1700 return (0);
1704 * Poll for interesting events on a stream pipe
1706 /* ARGSUSED */
1708 fifo_poll(vnode_t *vp, short events, int anyyet, short *reventsp,
1709 pollhead_t **phpp, caller_context_t *ct)
1711 fifonode_t *fnp, *fn_dest;
1712 fifolock_t *fn_lock;
1713 int retevents;
1714 struct stdata *stp;
1716 ASSERT(vp->v_stream != NULL);
1718 stp = vp->v_stream;
1719 retevents = 0;
1720 fnp = VTOF(vp);
1721 fn_dest = fnp->fn_dest;
1722 fn_lock = fnp->fn_lock;
1724 if (polllock(&stp->sd_pollist, &fn_lock->flk_lock) != 0) {
1725 *reventsp = POLLNVAL;
1726 return (0);
1730 * see if FIFO/pipe open
1732 if ((fnp->fn_flag & FIFOISOPEN) == 0) {
1733 if (((events & (POLLIN | POLLRDNORM | POLLPRI | POLLRDBAND)) &&
1734 fnp->fn_rcnt == 0) ||
1735 ((events & (POLLWRNORM | POLLWRBAND)) &&
1736 fnp->fn_wcnt == 0)) {
1737 mutex_exit(&fnp->fn_lock->flk_lock);
1738 *reventsp = POLLERR;
1739 return (0);
1744 * if not in fast mode, let the stream head take care of it
1746 if (!(fnp->fn_flag & FIFOFAST)) {
1747 mutex_exit(&fnp->fn_lock->flk_lock);
1748 goto stream_mode;
1752 * If this is a pipe.. check to see if the other
1753 * end is gone. If we are a fifo, check to see
1754 * if write end is gone.
1757 if ((fnp->fn_flag & ISPIPE) && (fn_dest->fn_open == 0)) {
1758 retevents = POLLHUP;
1759 } else if ((fnp->fn_flag & (FIFOCLOSE | ISPIPE)) == FIFOCLOSE &&
1760 (fn_dest->fn_wcnt == 0)) {
1762 * no writer at other end.
1763 * it was closed (versus yet to be opened)
1765 retevents = POLLHUP;
1766 } else if (events & (POLLWRNORM | POLLWRBAND)) {
1767 if (events & POLLWRNORM) {
1768 if (fn_dest->fn_count < Fifohiwat)
1769 retevents = POLLWRNORM;
1770 else
1771 fnp->fn_flag |= FIFOHIWATW;
1774 * This is always true for fast pipes
1775 * (Note: will go to STREAMS mode if band data is written)
1777 if (events & POLLWRBAND)
1778 retevents |= POLLWRBAND;
1780 if (events & (POLLIN | POLLRDNORM)) {
1781 if (fnp->fn_count)
1782 retevents |= (events & (POLLIN | POLLRDNORM));
1786 * if we happened to get something and we're not edge-triggered, return
1788 if ((*reventsp = (short)retevents) != 0 && !(events & POLLET)) {
1789 mutex_exit(&fnp->fn_lock->flk_lock);
1790 return (0);
1794 * If poll() has not found any events yet or we're edge-triggered, set
1795 * up event cell to wake up the poll if a requested event occurs on this
1796 * pipe/fifo.
1798 if (!anyyet) {
1799 if (events & POLLWRNORM)
1800 fnp->fn_flag |= FIFOPOLLW;
1801 if (events & (POLLIN | POLLRDNORM))
1802 fnp->fn_flag |= FIFOPOLLR;
1803 if (events & POLLRDBAND)
1804 fnp->fn_flag |= FIFOPOLLRBAND;
1806 * XXX Don't like exposing this from streams
1808 *phpp = &stp->sd_pollist;
1810 mutex_exit(&fnp->fn_lock->flk_lock);
1811 return (0);
1812 stream_mode:
1813 return (strpoll(stp, events, anyyet, reventsp, phpp));
1817 * POSIX pathconf() support.
1819 /* ARGSUSED */
1821 fifo_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
1822 caller_context_t *ct)
1824 ulong_t val;
1825 int error = 0;
1827 switch (cmd) {
1829 case _PC_LINK_MAX:
1830 val = MAXLINK;
1831 break;
1833 case _PC_MAX_CANON:
1834 val = MAX_CANON;
1835 break;
1837 case _PC_MAX_INPUT:
1838 val = MAX_INPUT;
1839 break;
1841 case _PC_NAME_MAX:
1842 error = EINVAL;
1843 break;
1845 case _PC_PATH_MAX:
1846 case _PC_SYMLINK_MAX:
1847 val = MAXPATHLEN;
1848 break;
1850 case _PC_PIPE_BUF:
1851 val = PIPE_BUF;
1852 break;
1854 case _PC_NO_TRUNC:
1855 if (vp->v_vfsp->vfs_flag & VFS_NOTRUNC)
1856 val = 1; /* NOTRUNC is enabled for vp */
1857 else
1858 val = (ulong_t)-1;
1859 break;
1861 case _PC_VDISABLE:
1862 val = _POSIX_VDISABLE;
1863 break;
1865 case _PC_CHOWN_RESTRICTED:
1866 if (rstchown)
1867 val = rstchown; /* chown restricted enabled */
1868 else
1869 val = (ulong_t)-1;
1870 break;
1872 case _PC_FILESIZEBITS:
1873 val = (ulong_t)-1;
1874 break;
1876 default:
1877 if (VTOF(vp)->fn_realvp)
1878 error = fop_pathconf(VTOF(vp)->fn_realvp, cmd,
1879 &val, cr, ct);
1880 else
1881 error = EINVAL;
1882 break;
1885 if (error == 0)
1886 *valp = val;
1887 return (error);
1891 * If shadowing a vnode, apply fop_setsecattr to it.
1892 * Otherwise, return NOSYS.
1895 fifo_setsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *crp,
1896 caller_context_t *ct)
1898 int error;
1901 * The acl(2) system call tries to grab the write lock on the
1902 * file when setting an ACL, but fifofs does not implement
1903 * fop_rwlock or fop_rwunlock, so we do it here instead.
1905 if (VTOF(vp)->fn_realvp) {
1906 (void) fop_rwlock(VTOF(vp)->fn_realvp, V_WRITELOCK_TRUE, ct);
1907 error = fop_setsecattr(VTOF(vp)->fn_realvp, vsap, flag,
1908 crp, ct);
1909 fop_rwunlock(VTOF(vp)->fn_realvp, V_WRITELOCK_TRUE, ct);
1910 return (error);
1911 } else
1912 return (fs_nosys());
1916 * If shadowing a vnode, apply fop_getsecattr to it. Otherwise, fabricate
1917 * an ACL from the permission bits that fifo_getattr() makes up.
1920 fifo_getsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *crp,
1921 caller_context_t *ct)
1923 if (VTOF(vp)->fn_realvp)
1924 return (fop_getsecattr(VTOF(vp)->fn_realvp, vsap, flag,
1925 crp, ct));
1926 else
1927 return (fs_fab_acl(vp, vsap, flag, crp, ct));
1932 * Set the FIFOSTAYFAST flag so nobody can turn the fifo into stream mode.
1933 * If the flag is already set then wait until it is removed - releasing
1934 * the lock.
1935 * If the fifo switches into stream mode while we are waiting, return failure.
1937 static boolean_t
1938 fifo_stayfast_enter(fifonode_t *fnp)
1940 ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock));
1941 while (fnp->fn_flag & FIFOSTAYFAST) {
1942 fnp->fn_flag |= FIFOWAITMODE;
1943 cv_wait(&fnp->fn_wait_cv, &fnp->fn_lock->flk_lock);
1944 fnp->fn_flag &= ~FIFOWAITMODE;
1946 if (!(fnp->fn_flag & FIFOFAST))
1947 return (B_FALSE);
1949 fnp->fn_flag |= FIFOSTAYFAST;
1950 return (B_TRUE);
1954 * Unset the FIFOSTAYFAST flag and notify anybody waiting for this flag
1955 * to be removed:
1956 * - threads wanting to turn into stream mode waiting in fifo_fastoff(),
1957 * - other writers threads waiting in fifo_stayfast_enter().
1959 static void
1960 fifo_stayfast_exit(fifonode_t *fnp)
1962 fifonode_t *fn_dest = fnp->fn_dest;
1964 ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock));
1966 fnp->fn_flag &= ~FIFOSTAYFAST;
1968 if (fnp->fn_flag & FIFOWAITMODE)
1969 cv_broadcast(&fnp->fn_wait_cv);
1971 if ((fnp->fn_flag & ISPIPE) && (fn_dest->fn_flag & FIFOWAITMODE))
1972 cv_broadcast(&fn_dest->fn_wait_cv);