2 * Copyright (c) 1990, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * Filesystem FIFO type ops. All entry points are MPSAFE. We primarily
35 * use v_token to interlock operations.
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/unistd.h>
40 #include <sys/kernel.h>
42 #include <sys/malloc.h>
43 #include <sys/thread2.h>
44 #include <sys/vnode.h>
45 #include <sys/socket.h>
46 #include <sys/socketvar.h>
47 #include <sys/filio.h>
48 #include <sys/fcntl.h>
50 #include <sys/event.h>
54 #include <sys/thread2.h>
59 * This structure is associated with the FIFO vnode and stores
60 * the state associated with the FIFO.
63 struct socket
*fi_readsock
;
64 struct socket
*fi_writesock
;
69 static int fifo_badop (void);
70 static int fifo_print (struct vop_print_args
*);
71 static int fifo_lookup (struct vop_old_lookup_args
*);
72 static int fifo_open (struct vop_open_args
*);
73 static int fifo_close (struct vop_close_args
*);
74 static int fifo_read (struct vop_read_args
*);
75 static int fifo_write (struct vop_write_args
*);
76 static int fifo_ioctl (struct vop_ioctl_args
*);
77 static int fifo_poll (struct vop_poll_args
*);
78 static int fifo_kqfilter (struct vop_kqfilter_args
*);
79 static int fifo_inactive (struct vop_inactive_args
*);
80 static int fifo_bmap (struct vop_bmap_args
*);
81 static int fifo_pathconf (struct vop_pathconf_args
*);
82 static int fifo_advlock (struct vop_advlock_args
*);
84 static void filt_fifordetach(struct knote
*kn
);
85 static int filt_fiforead(struct knote
*kn
, long hint
);
86 static void filt_fifowdetach(struct knote
*kn
);
87 static int filt_fifowrite(struct knote
*kn
, long hint
);
89 static struct filterops fiforead_filtops
=
90 { 1, NULL
, filt_fifordetach
, filt_fiforead
};
91 static struct filterops fifowrite_filtops
=
92 { 1, NULL
, filt_fifowdetach
, filt_fifowrite
};
94 struct vop_ops fifo_vnode_vops
= {
95 .vop_default
= vop_defaultop
,
96 .vop_access
= (void *)vop_ebadf
,
97 .vop_advlock
= fifo_advlock
,
98 .vop_bmap
= fifo_bmap
,
99 .vop_close
= fifo_close
,
100 .vop_old_create
= (void *)fifo_badop
,
101 .vop_getattr
= (void *)vop_ebadf
,
102 .vop_inactive
= fifo_inactive
,
103 .vop_ioctl
= fifo_ioctl
,
104 .vop_kqfilter
= fifo_kqfilter
,
105 .vop_old_link
= (void *)fifo_badop
,
106 .vop_old_lookup
= fifo_lookup
,
107 .vop_old_mkdir
= (void *)fifo_badop
,
108 .vop_old_mknod
= (void *)fifo_badop
,
109 .vop_open
= fifo_open
,
110 .vop_pathconf
= fifo_pathconf
,
111 .vop_poll
= fifo_poll
,
112 .vop_print
= fifo_print
,
113 .vop_read
= fifo_read
,
114 .vop_readdir
= (void *)fifo_badop
,
115 .vop_readlink
= (void *)fifo_badop
,
116 .vop_reallocblks
= (void *)fifo_badop
,
117 .vop_reclaim
= (void *)vop_null
,
118 .vop_old_remove
= (void *)fifo_badop
,
119 .vop_old_rename
= (void *)fifo_badop
,
120 .vop_old_rmdir
= (void *)fifo_badop
,
121 .vop_setattr
= (void *)vop_ebadf
,
122 .vop_old_symlink
= (void *)fifo_badop
,
123 .vop_write
= fifo_write
126 VNODEOP_SET(fifo_vnode_vops
);
128 static MALLOC_DEFINE(M_FIFOINFO
, "Fifo info", "Fifo info entries");
134 fifo_vnoperate(struct vop_generic_args
*ap
)
136 return (VOCALL(&fifo_vnode_vops
, ap
));
140 * Trivial lookup routine that always fails.
142 * fifo_lookup(struct vnode *a_dvp, struct vnode **a_vpp,
143 * struct componentname *a_cnp)
147 fifo_lookup(struct vop_old_lookup_args
*ap
)
154 * Open called to set up a new instance of a fifo or
155 * to find an active instance of a fifo.
157 * fifo_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
162 fifo_open(struct vop_open_args
*ap
)
164 struct thread
*td
= curthread
;
165 struct vnode
*vp
= ap
->a_vp
;
166 struct fifoinfo
*fip
;
167 struct socket
*rso
, *wso
;
171 lwkt_gettoken(&vlock
, &vp
->v_token
);
172 if ((fip
= vp
->v_fifoinfo
) == NULL
) {
173 MALLOC(fip
, struct fifoinfo
*, sizeof(*fip
), M_FIFOINFO
, M_WAITOK
);
174 vp
->v_fifoinfo
= fip
;
175 error
= socreate(AF_LOCAL
, &rso
, SOCK_STREAM
, 0, td
);
177 kfree(fip
, M_FIFOINFO
);
178 vp
->v_fifoinfo
= NULL
;
181 fip
->fi_readsock
= rso
;
182 error
= socreate(AF_LOCAL
, &wso
, SOCK_STREAM
, 0, td
);
184 soclose(rso
, FNONBLOCK
);
185 kfree(fip
, M_FIFOINFO
);
186 vp
->v_fifoinfo
= NULL
;
189 fip
->fi_writesock
= wso
;
190 error
= unp_connect2(wso
, rso
);
192 soclose(wso
, FNONBLOCK
);
193 soclose(rso
, FNONBLOCK
);
194 kfree(fip
, M_FIFOINFO
);
195 vp
->v_fifoinfo
= NULL
;
198 fip
->fi_readers
= fip
->fi_writers
= 0;
199 wso
->so_snd
.ssb_lowat
= PIPE_BUF
;
200 rso
->so_state
|= SS_CANTRCVMORE
;
202 if (ap
->a_mode
& FREAD
) {
204 if (fip
->fi_readers
== 1) {
205 fip
->fi_writesock
->so_state
&= ~SS_CANTSENDMORE
;
206 if (fip
->fi_writers
> 0) {
207 wakeup((caddr_t
)&fip
->fi_writers
);
208 sowwakeup(fip
->fi_writesock
);
212 if (ap
->a_mode
& FWRITE
) {
214 if (fip
->fi_writers
== 1) {
215 fip
->fi_readsock
->so_state
&= ~SS_CANTRCVMORE
;
216 if (fip
->fi_readers
> 0) {
217 wakeup((caddr_t
)&fip
->fi_readers
);
218 sorwakeup(fip
->fi_writesock
);
222 if ((ap
->a_mode
& FREAD
) && (ap
->a_mode
& O_NONBLOCK
) == 0) {
223 if (fip
->fi_writers
== 0) {
225 error
= tsleep((caddr_t
)&fip
->fi_readers
,
226 PCATCH
, "fifoor", 0);
227 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
231 * We must have got woken up because we had a writer.
232 * That (and not still having one) is the condition
233 * that we must wait for.
237 if (ap
->a_mode
& FWRITE
) {
238 if (ap
->a_mode
& O_NONBLOCK
) {
239 if (fip
->fi_readers
== 0) {
244 if (fip
->fi_readers
== 0) {
246 error
= tsleep((caddr_t
)&fip
->fi_writers
,
247 PCATCH
, "fifoow", 0);
248 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
252 * We must have got woken up because we had
253 * a reader. That (and not still having one)
254 * is the condition that we must wait for.
259 vsetflags(vp
, VNOTSEEKABLE
);
260 error
= vop_stdopen(ap
);
261 lwkt_reltoken(&vlock
);
264 vop_stdopen(ap
); /* bump opencount/writecount as appropriate */
265 VOP_CLOSE(vp
, ap
->a_mode
);
267 lwkt_reltoken(&vlock
);
274 * fifo_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
275 * struct ucred *a_cred)
279 fifo_read(struct vop_read_args
*ap
)
281 struct uio
*uio
= ap
->a_uio
;
282 struct socket
*rso
= ap
->a_vp
->v_fifoinfo
->fi_readsock
;
283 int error
, startresid
;
288 if (uio
->uio_rw
!= UIO_READ
)
289 panic("fifo_read mode");
291 if (uio
->uio_resid
== 0)
293 if (ap
->a_ioflag
& IO_NDELAY
)
294 flags
= MSG_FNONBLOCKING
;
297 startresid
= uio
->uio_resid
;
299 lwkt_gettoken(&vlock
, &ap
->a_vp
->v_token
);
300 error
= soreceive(rso
, NULL
, uio
, NULL
, NULL
, &flags
);
301 lwkt_reltoken(&vlock
);
302 vn_lock(ap
->a_vp
, LK_EXCLUSIVE
| LK_RETRY
);
309 * fifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
310 * struct ucred *a_cred)
314 fifo_write(struct vop_write_args
*ap
)
316 struct socket
*wso
= ap
->a_vp
->v_fifoinfo
->fi_writesock
;
317 struct thread
*td
= ap
->a_uio
->uio_td
;
323 if (ap
->a_uio
->uio_rw
!= UIO_WRITE
)
324 panic("fifo_write mode");
326 if (ap
->a_ioflag
& IO_NDELAY
)
327 flags
= MSG_FNONBLOCKING
;
331 lwkt_gettoken(&vlock
, &ap
->a_vp
->v_token
);
332 error
= sosend(wso
, NULL
, ap
->a_uio
, 0, NULL
, flags
, td
);
333 lwkt_reltoken(&vlock
);
334 vn_lock(ap
->a_vp
, LK_EXCLUSIVE
| LK_RETRY
);
339 * Device ioctl operation.
341 * fifo_ioctl(struct vnode *a_vp, int a_command, caddr_t a_data, int a_fflag,
342 * struct ucred *a_cred, struct sysmsg *a_sysmsg)
346 fifo_ioctl(struct vop_ioctl_args
*ap
)
348 struct file filetmp
; /* Local */
352 if (ap
->a_fflag
& FREAD
) {
353 filetmp
.f_data
= ap
->a_vp
->v_fifoinfo
->fi_readsock
;
354 lwkt_gettoken(&vlock
, &ap
->a_vp
->v_token
);
355 error
= soo_ioctl(&filetmp
, ap
->a_command
, ap
->a_data
,
356 ap
->a_cred
, ap
->a_sysmsg
);
357 lwkt_reltoken(&vlock
);
361 if (ap
->a_fflag
& FWRITE
) {
362 filetmp
.f_data
= ap
->a_vp
->v_fifoinfo
->fi_writesock
;
363 lwkt_gettoken(&vlock
, &ap
->a_vp
->v_token
);
364 error
= soo_ioctl(&filetmp
, ap
->a_command
, ap
->a_data
,
365 ap
->a_cred
, ap
->a_sysmsg
);
366 lwkt_reltoken(&vlock
);
374 * fifo_kqfilter(struct vnode *a_vp, struct knote *a_kn)
378 fifo_kqfilter(struct vop_kqfilter_args
*ap
)
380 struct vnode
*vp
= ap
->a_vp
;
381 struct fifoinfo
*fi
= vp
->v_fifoinfo
;
383 struct signalsockbuf
*ssb
;
386 lwkt_gettoken(&vlock
, &vp
->v_token
);
388 switch (ap
->a_kn
->kn_filter
) {
390 ap
->a_kn
->kn_fop
= &fiforead_filtops
;
391 so
= fi
->fi_readsock
;
395 ap
->a_kn
->kn_fop
= &fifowrite_filtops
;
396 so
= fi
->fi_writesock
;
400 lwkt_reltoken(&vlock
);
404 ap
->a_kn
->kn_hook
= (caddr_t
)vp
;
405 ssb_insert_knote(ssb
, ap
->a_kn
);
407 lwkt_reltoken(&vlock
);
412 filt_fifordetach(struct knote
*kn
)
414 struct vnode
*vp
= (void *)kn
->kn_hook
;
415 struct socket
*so
= vp
->v_fifoinfo
->fi_readsock
;
418 lwkt_gettoken(&vlock
, &vp
->v_token
);
419 ssb_remove_knote(&so
->so_rcv
, kn
);
420 lwkt_reltoken(&vlock
);
424 filt_fiforead(struct knote
*kn
, long hint
)
426 struct vnode
*vp
= (void *)kn
->kn_hook
;
427 struct socket
*so
= vp
->v_fifoinfo
->fi_readsock
;
430 lwkt_gettoken(&vlock
, &vp
->v_token
);
431 kn
->kn_data
= so
->so_rcv
.ssb_cc
;
432 if (so
->so_state
& SS_CANTRCVMORE
) {
433 kn
->kn_flags
|= EV_EOF
;
434 lwkt_reltoken(&vlock
);
437 kn
->kn_flags
&= ~EV_EOF
;
438 lwkt_reltoken(&vlock
);
439 return (kn
->kn_data
> 0);
443 filt_fifowdetach(struct knote
*kn
)
445 struct vnode
*vp
= (void *)kn
->kn_hook
;
446 struct socket
*so
= vp
->v_fifoinfo
->fi_writesock
;
449 lwkt_gettoken(&vlock
, &vp
->v_token
);
450 ssb_remove_knote(&so
->so_snd
, kn
);
451 lwkt_reltoken(&vlock
);
455 filt_fifowrite(struct knote
*kn
, long hint
)
457 struct vnode
*vp
= (void *)kn
->kn_hook
;
458 struct socket
*so
= vp
->v_fifoinfo
->fi_writesock
;
461 lwkt_gettoken(&vlock
, &vp
->v_token
);
462 kn
->kn_data
= ssb_space(&so
->so_snd
);
463 if (so
->so_state
& SS_CANTSENDMORE
) {
464 kn
->kn_flags
|= EV_EOF
;
465 lwkt_reltoken(&vlock
);
468 kn
->kn_flags
&= ~EV_EOF
;
469 lwkt_reltoken(&vlock
);
470 return (kn
->kn_data
>= so
->so_snd
.ssb_lowat
);
474 * fifo_poll(struct vnode *a_vp, int a_events, struct ucred *a_cred)
478 fifo_poll(struct vop_poll_args
*ap
)
481 int events
, revents
= 0;
484 lwkt_gettoken(&vlock
, &ap
->a_vp
->v_token
);
485 events
= ap
->a_events
&
486 (POLLIN
| POLLINIGNEOF
| POLLPRI
| POLLRDNORM
| POLLRDBAND
);
489 * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is
490 * not, then convert the first two to the last one. This
491 * tells the socket poll function to ignore EOF so that we
492 * block if there is no writer (and no data). Callers can
493 * set POLLINIGNEOF to get non-blocking behavior.
495 if (events
& (POLLIN
| POLLRDNORM
) &&
496 !(events
& POLLINIGNEOF
)) {
497 events
&= ~(POLLIN
| POLLRDNORM
);
498 events
|= POLLINIGNEOF
;
501 filetmp
.f_data
= ap
->a_vp
->v_fifoinfo
->fi_readsock
;
503 revents
|= soo_poll(&filetmp
, events
, ap
->a_cred
);
505 /* Reverse the above conversion. */
506 if ((revents
& POLLINIGNEOF
) &&
507 !(ap
->a_events
& POLLINIGNEOF
)) {
508 revents
|= (ap
->a_events
& (POLLIN
| POLLRDNORM
));
509 revents
&= ~POLLINIGNEOF
;
512 events
= ap
->a_events
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
);
514 filetmp
.f_data
= ap
->a_vp
->v_fifoinfo
->fi_writesock
;
516 revents
|= soo_poll(&filetmp
, events
, ap
->a_cred
);
518 lwkt_reltoken(&vlock
);
523 * fifo_inactive(struct vnode *a_vp)
526 fifo_inactive(struct vop_inactive_args
*ap
)
532 * This is a noop, simply returning what one has been given.
534 * fifo_bmap(struct vnode *a_vp, off_t a_loffset,
535 * off_t *a_doffsetp, int *a_runp, int *a_runb)
538 fifo_bmap(struct vop_bmap_args
*ap
)
540 if (ap
->a_doffsetp
!= NULL
)
541 *ap
->a_doffsetp
= ap
->a_loffset
;
542 if (ap
->a_runp
!= NULL
)
544 if (ap
->a_runb
!= NULL
)
550 * Device close routine
552 * fifo_close(struct vnode *a_vp, int a_fflag)
556 fifo_close(struct vop_close_args
*ap
)
558 struct vnode
*vp
= ap
->a_vp
;
559 struct fifoinfo
*fip
;
563 lwkt_gettoken(&vlock
, &vp
->v_token
);
564 fip
= vp
->v_fifoinfo
;
565 if (ap
->a_fflag
& FREAD
) {
567 if (fip
->fi_readers
== 0)
568 socantsendmore(fip
->fi_writesock
);
570 if (ap
->a_fflag
& FWRITE
) {
572 if (fip
->fi_writers
== 0)
573 socantrcvmore(fip
->fi_readsock
);
575 if (vp
->v_sysref
.refcnt
> 1) {
577 lwkt_reltoken(&vlock
);
580 error1
= soclose(fip
->fi_readsock
, FNONBLOCK
);
581 error2
= soclose(fip
->fi_writesock
, FNONBLOCK
);
582 FREE(fip
, M_FIFOINFO
);
583 vp
->v_fifoinfo
= NULL
;
589 lwkt_reltoken(&vlock
);
595 * Print out internal contents of a fifo vnode.
598 fifo_printinfo(struct vnode
*vp
)
600 struct fifoinfo
*fip
= vp
->v_fifoinfo
;
602 kprintf(", fifo with %ld readers and %ld writers",
603 fip
->fi_readers
, fip
->fi_writers
);
608 * Print out the contents of a fifo vnode.
610 * fifo_print(struct vnode *a_vp)
613 fifo_print(struct vop_print_args
*ap
)
615 kprintf("tag VT_NON");
616 fifo_printinfo(ap
->a_vp
);
622 * Return POSIX pathconf information applicable to fifo's.
624 * fifo_pathconf(struct vnode *a_vp, int a_name, int *a_retval)
627 fifo_pathconf(struct vop_pathconf_args
*ap
)
629 switch (ap
->a_name
) {
631 *ap
->a_retval
= LINK_MAX
;
634 *ap
->a_retval
= PIPE_BUF
;
636 case _PC_CHOWN_RESTRICTED
:
646 * Fifo advisory byte-level locks.
648 * fifo_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl,
653 fifo_advlock(struct vop_advlock_args
*ap
)
655 return ((ap
->a_flags
& F_POSIX
) ? EINVAL
: EOPNOTSUPP
);
664 panic("fifo_badop called");