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