Merge branch 'vendor/ZSTD' into master
[dragonfly.git] / sys / vfs / fifofs / fifo_vnops.c
1 /*
2  * Copyright (c) 1990, 1993, 1995
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 /*
30  * Filesystem FIFO type ops.  All entry points are MPSAFE.
31  */
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/unistd.h>
35 #include <sys/kernel.h>
36 #include <sys/lock.h>
37 #include <sys/malloc.h>
38 #include <sys/vnode.h>
39 #include <sys/socket.h>
40 #include <sys/socketvar.h>
41 #include <sys/filio.h>
42 #include <sys/fcntl.h>
43 #include <sys/file.h>
44 #include <sys/event.h>
45 #include <sys/un.h>
46
47 #include <sys/socketvar2.h>
48
49 #include "fifo.h"
50
51 /*
52  * This structure is associated with the FIFO vnode and stores
53  * the state associated with the FIFO.
54  */
55 struct fifoinfo {
56         struct socket   *fi_readsock;
57         struct socket   *fi_writesock;
58         long            fi_readers;
59         long            fi_writers;
60 };
61
62 #define FIFO_LOCK_POOL  128
63 #define FIFO_LOCK_MASK  (FIFO_LOCK_POOL - 1)
64
65 static int      fifo_badop (void);
66 static int      fifo_print (struct vop_print_args *);
67 static int      fifo_lookup (struct vop_old_lookup_args *);
68 static int      fifo_open (struct vop_open_args *);
69 static int      fifo_close (struct vop_close_args *);
70 static int      fifo_read (struct vop_read_args *);
71 static int      fifo_write (struct vop_write_args *);
72 static int      fifo_ioctl (struct vop_ioctl_args *);
73 static int      fifo_kqfilter (struct vop_kqfilter_args *);
74 static int      fifo_inactive (struct  vop_inactive_args *);
75 static int      fifo_bmap (struct vop_bmap_args *);
76 static int      fifo_pathconf (struct vop_pathconf_args *);
77 static int      fifo_advlock (struct vop_advlock_args *);
78
79 static void     filt_fifordetach(struct knote *kn);
80 static int      filt_fiforead(struct knote *kn, long hint);
81 static void     filt_fifowdetach(struct knote *kn);
82 static int      filt_fifowrite(struct knote *kn, long hint);
83
84 static struct filterops fiforead_filtops =
85         { FILTEROP_ISFD, NULL, filt_fifordetach, filt_fiforead };
86 static struct filterops fifowrite_filtops =
87         { FILTEROP_ISFD, NULL, filt_fifowdetach, filt_fifowrite };
88
89 struct vop_ops fifo_vnode_vops = {
90         .vop_default =          vop_defaultop,
91         .vop_access =           (void *)vop_ebadf,
92         .vop_advlock =          fifo_advlock,
93         .vop_bmap =             fifo_bmap,
94         .vop_close =            fifo_close,
95         .vop_old_create =       (void *)fifo_badop,
96         .vop_getattr =          (void *)vop_ebadf,
97         .vop_inactive =         fifo_inactive,
98         .vop_ioctl =            fifo_ioctl,
99         .vop_kqfilter =         fifo_kqfilter,
100         .vop_old_link =         (void *)fifo_badop,
101         .vop_old_lookup =       fifo_lookup,
102         .vop_old_mkdir =        (void *)fifo_badop,
103         .vop_old_mknod =        (void *)fifo_badop,
104         .vop_open =             fifo_open,
105         .vop_pathconf =         fifo_pathconf,
106         .vop_print =            fifo_print,
107         .vop_read =             fifo_read,
108         .vop_readdir =          (void *)fifo_badop,
109         .vop_readlink =         (void *)fifo_badop,
110         .vop_reallocblks =      (void *)fifo_badop,
111         .vop_reclaim =          (void *)vop_null,
112         .vop_old_remove =       (void *)fifo_badop,
113         .vop_old_rename =       (void *)fifo_badop,
114         .vop_old_rmdir =        (void *)fifo_badop,
115         .vop_setattr =          (void *)vop_ebadf,
116         .vop_old_symlink =      (void *)fifo_badop,
117         .vop_write =            fifo_write
118 };
119
120 VNODEOP_SET(fifo_vnode_vops);
121
122 static MALLOC_DEFINE(M_FIFOINFO, "Fifo info", "Fifo info entries");
123
124 /*
125  * The vnode might be using a shared lock, we need an exclusive lock
126  * for open/close sequencing.  Create a little pool of locks.
127  */
128 static struct lock fifo_locks[FIFO_LOCK_POOL];
129
130 static __inline
131 void
132 fifo_lock(struct vnode *vp)
133 {
134         int hv;
135
136         hv = ((intptr_t)vp / sizeof(*vp)) & FIFO_LOCK_MASK;
137         lockmgr(&fifo_locks[hv], LK_EXCLUSIVE);
138 }
139
140 static __inline
141 void
142 fifo_unlock(struct vnode *vp)
143 {
144         int hv;
145
146         hv = ((intptr_t)vp / sizeof(*vp)) & FIFO_LOCK_MASK;
147         lockmgr(&fifo_locks[hv], LK_RELEASE);
148 }
149
150 static void
151 fifo_init(void)
152 {
153         int i;
154
155         for (i = 0; i < FIFO_LOCK_POOL; ++i)
156                 lockinit(&fifo_locks[i], "fifolk", 0, 0);
157 }
158 SYSINIT(fifoinit, SI_SUB_PSEUDO, SI_ORDER_ANY, fifo_init, NULL);
159
160 /*
161  * fifo_vnoperate()
162  */
163 int
164 fifo_vnoperate(struct vop_generic_args *ap)
165 {
166         return (VOCALL(&fifo_vnode_vops, ap));
167 }
168
169 /*
170  * Trivial lookup routine that always fails.
171  *
172  * fifo_lookup(struct vnode *a_dvp, struct vnode **a_vpp,
173  *             struct componentname *a_cnp)
174  */
175 /* ARGSUSED */
176 static int
177 fifo_lookup(struct vop_old_lookup_args *ap)
178 {
179         *ap->a_vpp = NULL;
180         return (ENOTDIR);
181 }
182
183 /*
184  * Create/destroy the socket pairs for the fifo
185  */
186 static
187 struct fifoinfo *
188 fifo_fip_create(int *errorp)
189 {
190         struct thread *td = curthread;
191         struct fifoinfo *fip;
192         struct socket *rso, *wso;
193
194         fip = kmalloc(sizeof(*fip), M_FIFOINFO, M_WAITOK);
195         *errorp = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, td);
196         if (*errorp) {
197                 kfree(fip, M_FIFOINFO);
198                 return NULL;
199         }
200         rso->so_options &= ~SO_LINGER;
201         fip->fi_readsock = rso;
202         *errorp = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, td);
203         if (*errorp) {
204                 soclose(rso, FNONBLOCK);
205                 kfree(fip, M_FIFOINFO);
206                 return NULL;
207         }
208         wso->so_options &= ~SO_LINGER;
209         fip->fi_writesock = wso;
210         *errorp = unp_connect2(wso, rso);
211         if (*errorp) {
212                 soclose(wso, FNONBLOCK);
213                 soclose(rso, FNONBLOCK);
214                 kfree(fip, M_FIFOINFO);
215                 return NULL;
216         }
217         fip->fi_readers = fip->fi_writers = 0;
218         wso->so_snd.ssb_lowat = PIPE_BUF;
219         sosetstate(rso, SS_CANTRCVMORE);
220
221         return fip;
222 }
223
224 static int
225 fifo_fip_destroy(struct fifoinfo *fip)
226 {
227         int error1, error;
228
229         error1 = soclose(fip->fi_readsock, FNONBLOCK);
230         error = soclose(fip->fi_writesock, FNONBLOCK);
231         kfree(fip, M_FIFOINFO);
232         if (error1)
233                 error = error1;
234         return error;
235 }
236
237 /*
238  * Open called to set up a new instance of a fifo or
239  * to find an active instance of a fifo.
240  *
241  * fifo_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
242  *           struct file *a_fp)
243  */
244 /* ARGSUSED */
245 static int
246 fifo_open(struct vop_open_args *ap)
247 {
248         struct vnode *vp = ap->a_vp;
249         struct fifoinfo *fip;
250         int error;
251
252         error = 0;
253
254         /*
255          * Create the fip if necessary
256          */
257         fifo_lock(vp);
258         if ((fip = vp->v_fifoinfo) == NULL) {
259                 fip = fifo_fip_create(&error);
260                 if (fip == NULL) {
261                         fifo_unlock(vp);
262                         return error;
263                 }
264                 vp->v_fifoinfo = fip;
265         }
266
267         /*
268          * Adjust fi_readers and fi_writers interlocked and issue wakeups
269          * as appropriate.
270          */
271         if (ap->a_mode & FREAD) {
272                 fip->fi_readers++;
273                 if (fip->fi_readers == 1) {
274                         soisreconnected(fip->fi_writesock);
275                         if (fip->fi_writers > 0) {
276                                 wakeup((caddr_t)&fip->fi_writers);
277                                 sowwakeup(fip->fi_writesock);
278                         }
279                 }
280         }
281         if (ap->a_mode & FWRITE) {
282                 fip->fi_writers++;
283                 if (fip->fi_writers == 1) {
284                         soisreconnected(fip->fi_readsock);
285                         if (fip->fi_readers > 0) {
286                                 wakeup((caddr_t)&fip->fi_readers);
287                                 sorwakeup(fip->fi_writesock);
288                         }
289                 }
290         }
291
292         /*
293          * Handle blocking as appropriate
294          */
295         if ((ap->a_mode & FREAD) && (ap->a_mode & O_NONBLOCK) == 0) {
296                 if (fip->fi_writers == 0) {
297                         fifo_unlock(vp);
298                         vn_unlock(vp);
299                         error = tsleep((caddr_t)&fip->fi_readers,
300                                        PCATCH, "fifoor", 0);
301                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
302                         fifo_lock(vp);
303                         if (error)
304                                 goto bad;
305                         /*
306                          * We must have got woken up because we had a writer.
307                          * That (and not still having one) is the condition
308                          * that we must wait for.
309                          */
310                 }
311         }
312         if (ap->a_mode & FWRITE) {
313                 if (ap->a_mode & O_NONBLOCK) {
314                         if (fip->fi_readers == 0) {
315                                 error = ENXIO;
316                                 goto bad;
317                         }
318                 } else {
319                         if (fip->fi_readers == 0) {
320                                 fifo_unlock(vp);
321                                 vn_unlock(vp);
322                                 error = tsleep((caddr_t)&fip->fi_writers,
323                                                PCATCH, "fifoow", 0);
324                                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
325                                 fifo_lock(vp);
326                                 if (error)
327                                         goto bad;
328                                 /*
329                                  * We must have got woken up because we had
330                                  * a reader.  That (and not still having one)
331                                  * is the condition that we must wait for.
332                                  */
333                         }
334                 }
335         }
336         vsetflags(vp, VNOTSEEKABLE);
337         error = vop_stdopen(ap);
338         fifo_unlock(vp);
339
340         return (error);
341
342 bad:
343         if (ap->a_mode & FREAD) {
344                 fip->fi_readers--;
345                 if (fip->fi_readers == 0)
346                         soisdisconnected(fip->fi_writesock);
347         }
348         if (ap->a_mode & FWRITE) {
349                 fip->fi_writers--;
350                 if (fip->fi_writers == 0)
351                         soisdisconnected(fip->fi_readsock);
352         }
353         if (fip->fi_readers == 0 && fip->fi_writers == 0) {
354                 vp->v_fifoinfo = NULL;
355                 (void)fifo_fip_destroy(fip);
356         }
357         fifo_unlock(vp);
358
359         return (error);
360 }
361
362 /*
363  * Vnode op for read
364  *
365  * fifo_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
366  *           struct ucred *a_cred)
367  */
368 /* ARGSUSED */
369 static int
370 fifo_read(struct vop_read_args *ap)
371 {
372         struct uio *uio = ap->a_uio;
373         struct vnode *vp = ap->a_vp;
374         struct socket *rso = vp->v_fifoinfo->fi_readsock;
375         int error;
376         int flags;
377
378 #ifdef DIAGNOSTIC
379         if (uio->uio_rw != UIO_READ)
380                 panic("fifo_read mode");
381 #endif
382         if (uio->uio_resid == 0)
383                 return (0);
384         if (ap->a_ioflag & IO_NDELAY)
385                 flags = MSG_FNONBLOCKING;
386         else
387                 flags = 0;
388         vn_unlock(vp);
389         lwkt_gettoken(&vp->v_token);
390         error = soreceive(rso, NULL, uio, NULL, NULL, &flags);
391         lwkt_reltoken(&vp->v_token);
392         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
393         return (error);
394 }
395
396 /*
397  * Vnode op for write
398  *
399  * fifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
400  *            struct ucred *a_cred)
401  */
402 /* ARGSUSED */
403 static int
404 fifo_write(struct vop_write_args *ap)
405 {
406         struct thread *td = ap->a_uio->uio_td;
407         struct vnode *vp = ap->a_vp;
408         struct socket *wso = vp->v_fifoinfo->fi_writesock;
409         int error;
410         int flags;
411
412 #ifdef DIAGNOSTIC
413         if (ap->a_uio->uio_rw != UIO_WRITE)
414                 panic("fifo_write mode");
415 #endif
416         if (ap->a_ioflag & IO_NDELAY)
417                 flags = MSG_FNONBLOCKING;
418         else
419                 flags = 0;
420         vn_unlock(vp);
421         lwkt_gettoken(&vp->v_token);
422         error = sosend(wso, NULL, ap->a_uio, 0, NULL, flags, td);
423         lwkt_reltoken(&vp->v_token);
424         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
425         return (error);
426 }
427
428 /*
429  * Device ioctl operation.
430  *
431  * fifo_ioctl(struct vnode *a_vp, int a_command, caddr_t a_data, int a_fflag,
432  *            struct ucred *a_cred, struct sysmsg *a_sysmsg)
433  */
434 /* ARGSUSED */
435 static int
436 fifo_ioctl(struct vop_ioctl_args *ap)
437 {
438         struct file filetmp;    /* Local */
439         struct vnode *vp = ap->a_vp;
440         int error;
441
442         if (ap->a_fflag & FREAD) {
443                 filetmp.f_data = vp->v_fifoinfo->fi_readsock;
444                 lwkt_gettoken(&vp->v_token);
445                 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data,
446                                   ap->a_cred, ap->a_sysmsg);
447                 lwkt_reltoken(&vp->v_token);
448                 if (error)
449                         return (error);
450         }
451         if (ap->a_fflag & FWRITE) {
452                 filetmp.f_data = vp->v_fifoinfo->fi_writesock;
453                 lwkt_gettoken(&vp->v_token);
454                 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data,
455                                   ap->a_cred, ap->a_sysmsg);
456                 lwkt_reltoken(&vp->v_token);
457                 if (error)
458                         return (error);
459         }
460         return (0);
461 }
462
463 /*
464  * fifo_kqfilter(struct vnode *a_vp, struct knote *a_kn)
465  */
466 /* ARGSUSED */
467 static int
468 fifo_kqfilter(struct vop_kqfilter_args *ap)
469 {
470         struct vnode *vp = ap->a_vp;
471         struct fifoinfo *fi = vp->v_fifoinfo;
472         struct socket *so;
473         struct signalsockbuf *ssb;
474
475         lwkt_gettoken(&vp->v_token);
476
477         switch (ap->a_kn->kn_filter) {
478         case EVFILT_READ:
479                 ap->a_kn->kn_fop = &fiforead_filtops;
480                 so = fi->fi_readsock;
481                 ssb = &so->so_rcv;
482                 break;
483         case EVFILT_WRITE:
484                 ap->a_kn->kn_fop = &fifowrite_filtops;
485                 so = fi->fi_writesock;
486                 ssb = &so->so_snd;
487                 break;
488         default:
489                 lwkt_reltoken(&vp->v_token);
490                 return (EOPNOTSUPP);
491         }
492
493         ap->a_kn->kn_hook = (caddr_t)vp;
494         ssb_insert_knote(ssb, ap->a_kn);
495
496         lwkt_reltoken(&vp->v_token);
497         return (0);
498 }
499
500 static void
501 filt_fifordetach(struct knote *kn)
502 {
503         struct vnode *vp = (void *)kn->kn_hook;
504         struct socket *so = vp->v_fifoinfo->fi_readsock;
505
506         lwkt_gettoken(&vp->v_token);
507         ssb_remove_knote(&so->so_rcv, kn);
508         lwkt_reltoken(&vp->v_token);
509 }
510
511 static int
512 filt_fiforead(struct knote *kn, long hint)
513 {
514         struct vnode *vp = (void *)kn->kn_hook;
515         struct socket *so = vp->v_fifoinfo->fi_readsock;
516
517         lwkt_gettoken(&vp->v_token);
518         kn->kn_data = so->so_rcv.ssb_cc;
519         if ((kn->kn_sfflags & NOTE_OLDAPI) == 0 &&
520             so->so_state & SS_ISDISCONNECTED) {
521                 if (kn->kn_data == 0)
522                         kn->kn_flags |= EV_NODATA;
523                 kn->kn_flags |= EV_EOF;
524                 lwkt_reltoken(&vp->v_token);
525                 return (1);
526         }
527         kn->kn_flags &= ~(EV_EOF | EV_NODATA);
528         lwkt_reltoken(&vp->v_token);
529         return (kn->kn_data > 0);
530 }
531
532 static void
533 filt_fifowdetach(struct knote *kn)
534 {
535         struct vnode *vp = (void *)kn->kn_hook;
536         struct socket *so = vp->v_fifoinfo->fi_writesock;
537
538         lwkt_gettoken(&vp->v_token);
539         ssb_remove_knote(&so->so_snd, kn);
540         lwkt_reltoken(&vp->v_token);
541 }
542
543 static int
544 filt_fifowrite(struct knote *kn, long hint)
545 {
546         struct vnode *vp = (void *)kn->kn_hook;
547         struct socket *so = vp->v_fifoinfo->fi_writesock;
548
549         lwkt_gettoken(&vp->v_token);
550         kn->kn_data = ssb_space(&so->so_snd);
551         if (so->so_state & SS_ISDISCONNECTED) {
552                 kn->kn_flags |= (EV_EOF | EV_NODATA);
553                 lwkt_reltoken(&vp->v_token);
554                 return (1);
555         }
556         kn->kn_flags &= ~(EV_EOF | EV_NODATA);
557         lwkt_reltoken(&vp->v_token);
558         return (kn->kn_data >= so->so_snd.ssb_lowat);
559 }
560
561 /*
562  * fifo_inactive(struct vnode *a_vp)
563  */
564 static int
565 fifo_inactive(struct vop_inactive_args *ap)
566 {
567         return (0);
568 }
569
570 /*
571  * This is a noop, simply returning what one has been given.
572  *
573  * fifo_bmap(struct vnode *a_vp, off_t a_loffset, 
574  *           off_t *a_doffsetp, int *a_runp, int *a_runb)
575  */
576 static int
577 fifo_bmap(struct vop_bmap_args *ap)
578 {
579         if (ap->a_doffsetp != NULL)
580                 *ap->a_doffsetp = ap->a_loffset;
581         if (ap->a_runp != NULL)
582                 *ap->a_runp = 0;
583         if (ap->a_runb != NULL)
584                 *ap->a_runb = 0;
585         return (0);
586 }
587
588 /*
589  * Device close routine
590  *
591  * fifo_close(struct vnode *a_vp, int a_fflag)
592  */
593 /* ARGSUSED */
594 static int
595 fifo_close(struct vop_close_args *ap)
596 {
597         struct vnode *vp = ap->a_vp;
598         struct fifoinfo *fip;
599         int error;
600
601         fifo_lock(vp);
602         fip = vp->v_fifoinfo;
603         if (fip == NULL) {
604                 vop_stdclose(ap);
605                 fifo_unlock(vp);
606                 return 0;
607         }
608         if (ap->a_fflag & FREAD) {
609                 fip->fi_readers--;
610                 if (fip->fi_readers == 0)
611                         soisdisconnected(fip->fi_writesock);
612         }
613         if (ap->a_fflag & FWRITE) {
614                 fip->fi_writers--;
615                 if (fip->fi_writers == 0)
616                         soisdisconnected(fip->fi_readsock);
617         }
618         if (fip->fi_readers == 0 && fip->fi_writers == 0) {
619                 vp->v_fifoinfo = NULL;
620                 error = fifo_fip_destroy(fip);
621         } else {
622                 error = 0;
623         }
624         vop_stdclose(ap);
625         fifo_unlock(vp);
626
627         return error;
628 }
629
630 /*
631  * Print out internal contents of a fifo vnode.
632  */
633 int
634 fifo_printinfo(struct vnode *vp)
635 {
636         struct fifoinfo *fip = vp->v_fifoinfo;
637
638         kprintf(", fifo with %ld readers and %ld writers",
639                 fip->fi_readers, fip->fi_writers);
640         return (0);
641 }
642
643 /*
644  * Print out the contents of a fifo vnode.
645  *
646  * fifo_print(struct vnode *a_vp)
647  */
648 static int
649 fifo_print(struct vop_print_args *ap)
650 {
651         kprintf("tag VT_NON");
652         fifo_printinfo(ap->a_vp);
653         kprintf("\n");
654         return (0);
655 }
656
657 /*
658  * Return POSIX pathconf information applicable to fifo's.
659  *
660  * fifo_pathconf(struct vnode *a_vp, int a_name, int *a_retval)
661  */
662 int
663 fifo_pathconf(struct vop_pathconf_args *ap)
664 {
665         switch (ap->a_name) {
666         case _PC_LINK_MAX:
667                 *ap->a_retval = LINK_MAX;
668                 return (0);
669         case _PC_PIPE_BUF:
670                 *ap->a_retval = PIPE_BUF;
671                 return (0);
672         case _PC_CHOWN_RESTRICTED:
673                 *ap->a_retval = 1;
674                 return (0);
675         default:
676                 return (EINVAL);
677         }
678         /* NOTREACHED */
679 }
680
681 /*
682  * Fifo advisory byte-level locks.
683  *
684  * fifo_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl,
685  *              int a_flags)
686  */
687 /* ARGSUSED */
688 static int
689 fifo_advlock(struct vop_advlock_args *ap)
690 {
691         return ((ap->a_flags & F_POSIX) ? EINVAL : EOPNOTSUPP);
692 }
693
694 /*
695  * Fifo bad operation
696  */
697 static int
698 fifo_badop(void)
699 {
700         panic("fifo_badop called");
701         /* NOTREACHED */
702 }