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
);
387 switch (ap
->a_kn
->kn_filter
) {
389 ap
->a_kn
->kn_fop
= &fiforead_filtops
;
390 so
= fi
->fi_readsock
;
394 ap
->a_kn
->kn_fop
= &fifowrite_filtops
;
395 so
= fi
->fi_writesock
;
402 ap
->a_kn
->kn_hook
= (caddr_t
)vp
;
403 ssb_insert_knote(ssb
, ap
->a_kn
);
405 lwkt_reltoken(&vlock
);
410 filt_fifordetach(struct knote
*kn
)
412 struct vnode
*vp
= (void *)kn
->kn_hook
;
413 struct socket
*so
= vp
->v_fifoinfo
->fi_readsock
;
416 lwkt_gettoken(&vlock
, &vp
->v_token
);
417 ssb_remove_knote(&so
->so_rcv
, kn
);
418 lwkt_reltoken(&vlock
);
422 filt_fiforead(struct knote
*kn
, long hint
)
424 struct vnode
*vp
= (void *)kn
->kn_hook
;
425 struct socket
*so
= vp
->v_fifoinfo
->fi_writesock
;
428 lwkt_gettoken(&vlock
, &vp
->v_token
);
429 kn
->kn_data
= so
->so_rcv
.ssb_cc
;
430 if (so
->so_state
& SS_CANTRCVMORE
) {
431 kn
->kn_flags
|= EV_EOF
;
434 kn
->kn_flags
&= ~EV_EOF
;
435 lwkt_reltoken(&vlock
);
436 return (kn
->kn_data
> 0);
440 filt_fifowdetach(struct knote
*kn
)
442 struct vnode
*vp
= (void *)kn
->kn_hook
;
443 struct socket
*so
= vp
->v_fifoinfo
->fi_writesock
;
446 lwkt_gettoken(&vlock
, &vp
->v_token
);
447 ssb_remove_knote(&so
->so_snd
, kn
);
448 lwkt_reltoken(&vlock
);
452 filt_fifowrite(struct knote
*kn
, long hint
)
454 struct vnode
*vp
= (void *)kn
->kn_hook
;
455 struct socket
*so
= vp
->v_fifoinfo
->fi_writesock
;
458 lwkt_gettoken(&vlock
, &vp
->v_token
);
459 kn
->kn_data
= ssb_space(&so
->so_snd
);
460 if (so
->so_state
& SS_CANTSENDMORE
) {
461 kn
->kn_flags
|= EV_EOF
;
464 kn
->kn_flags
&= ~EV_EOF
;
465 lwkt_reltoken(&vlock
);
466 return (kn
->kn_data
>= so
->so_snd
.ssb_lowat
);
470 * fifo_poll(struct vnode *a_vp, int a_events, struct ucred *a_cred)
474 fifo_poll(struct vop_poll_args
*ap
)
477 int events
, revents
= 0;
480 lwkt_gettoken(&vlock
, &ap
->a_vp
->v_token
);
481 events
= ap
->a_events
&
482 (POLLIN
| POLLINIGNEOF
| POLLPRI
| POLLRDNORM
| POLLRDBAND
);
485 * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is
486 * not, then convert the first two to the last one. This
487 * tells the socket poll function to ignore EOF so that we
488 * block if there is no writer (and no data). Callers can
489 * set POLLINIGNEOF to get non-blocking behavior.
491 if (events
& (POLLIN
| POLLRDNORM
) &&
492 !(events
& POLLINIGNEOF
)) {
493 events
&= ~(POLLIN
| POLLRDNORM
);
494 events
|= POLLINIGNEOF
;
497 filetmp
.f_data
= ap
->a_vp
->v_fifoinfo
->fi_readsock
;
499 revents
|= soo_poll(&filetmp
, events
, ap
->a_cred
);
501 /* Reverse the above conversion. */
502 if ((revents
& POLLINIGNEOF
) &&
503 !(ap
->a_events
& POLLINIGNEOF
)) {
504 revents
|= (ap
->a_events
& (POLLIN
| POLLRDNORM
));
505 revents
&= ~POLLINIGNEOF
;
508 events
= ap
->a_events
& (POLLOUT
| POLLWRNORM
| POLLWRBAND
);
510 filetmp
.f_data
= ap
->a_vp
->v_fifoinfo
->fi_writesock
;
512 revents
|= soo_poll(&filetmp
, events
, ap
->a_cred
);
514 lwkt_reltoken(&vlock
);
519 * fifo_inactive(struct vnode *a_vp)
522 fifo_inactive(struct vop_inactive_args
*ap
)
528 * This is a noop, simply returning what one has been given.
530 * fifo_bmap(struct vnode *a_vp, off_t a_loffset,
531 * off_t *a_doffsetp, int *a_runp, int *a_runb)
534 fifo_bmap(struct vop_bmap_args
*ap
)
536 if (ap
->a_doffsetp
!= NULL
)
537 *ap
->a_doffsetp
= ap
->a_loffset
;
538 if (ap
->a_runp
!= NULL
)
540 if (ap
->a_runb
!= NULL
)
546 * Device close routine
548 * fifo_close(struct vnode *a_vp, int a_fflag)
552 fifo_close(struct vop_close_args
*ap
)
554 struct vnode
*vp
= ap
->a_vp
;
555 struct fifoinfo
*fip
;
559 lwkt_gettoken(&vlock
, &vp
->v_token
);
560 fip
= vp
->v_fifoinfo
;
561 if (ap
->a_fflag
& FREAD
) {
563 if (fip
->fi_readers
== 0)
564 socantsendmore(fip
->fi_writesock
);
566 if (ap
->a_fflag
& FWRITE
) {
568 if (fip
->fi_writers
== 0)
569 socantrcvmore(fip
->fi_readsock
);
571 if (vp
->v_sysref
.refcnt
> 1) {
573 lwkt_reltoken(&vlock
);
576 error1
= soclose(fip
->fi_readsock
, FNONBLOCK
);
577 error2
= soclose(fip
->fi_writesock
, FNONBLOCK
);
578 FREE(fip
, M_FIFOINFO
);
579 vp
->v_fifoinfo
= NULL
;
585 lwkt_reltoken(&vlock
);
591 * Print out internal contents of a fifo vnode.
594 fifo_printinfo(struct vnode
*vp
)
596 struct fifoinfo
*fip
= vp
->v_fifoinfo
;
598 kprintf(", fifo with %ld readers and %ld writers",
599 fip
->fi_readers
, fip
->fi_writers
);
604 * Print out the contents of a fifo vnode.
606 * fifo_print(struct vnode *a_vp)
609 fifo_print(struct vop_print_args
*ap
)
611 kprintf("tag VT_NON");
612 fifo_printinfo(ap
->a_vp
);
618 * Return POSIX pathconf information applicable to fifo's.
620 * fifo_pathconf(struct vnode *a_vp, int a_name, int *a_retval)
623 fifo_pathconf(struct vop_pathconf_args
*ap
)
625 switch (ap
->a_name
) {
627 *ap
->a_retval
= LINK_MAX
;
630 *ap
->a_retval
= PIPE_BUF
;
632 case _PC_CHOWN_RESTRICTED
:
642 * Fifo advisory byte-level locks.
644 * fifo_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl,
649 fifo_advlock(struct vop_advlock_args
*ap
)
651 return ((ap
->a_flags
& F_POSIX
) ? EINVAL
: EOPNOTSUPP
);
660 panic("fifo_badop called");