vnode interface conversion
[unix-history] / usr / src / sys / miscfs / fifofs / fifo_vnops.c
CommitLineData
cc6b488e
KM
1/*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
dbf0c423 5 * %sccs.include.redist.c%
cc6b488e 6 *
ea67b335 7 * @(#)fifo_vnops.c 7.13 (Berkeley) %G%
cc6b488e
KM
8 */
9
10#include "param.h"
063b2136 11#include "proc.h"
cc6b488e
KM
12#include "time.h"
13#include "namei.h"
14#include "vnode.h"
15#include "socket.h"
16#include "socketvar.h"
17#include "stat.h"
8429d022 18#include "systm.h"
cc6b488e
KM
19#include "ioctl.h"
20#include "file.h"
81b4c293 21#include "fifo.h"
cc6b488e
KM
22#include "errno.h"
23#include "malloc.h"
24
25/*
26 * This structure is associated with the FIFO vnode and stores
27 * the state associated with the FIFO.
28 */
29struct fifoinfo {
30 struct socket *fi_readsock;
31 struct socket *fi_writesock;
32 long fi_readers;
33 long fi_writers;
34};
35
9342689a
JH
36int (**fifo_vnodeop_p)();
37struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
38 { &vop_default_desc, vn_default_error },
39 { &vop_lookup_desc, fifo_lookup }, /* lookup */
40 { &vop_create_desc, fifo_create }, /* create */
41 { &vop_mknod_desc, fifo_mknod }, /* mknod */
42 { &vop_open_desc, fifo_open }, /* open */
43 { &vop_close_desc, fifo_close }, /* close */
44 { &vop_access_desc, fifo_access }, /* access */
45 { &vop_getattr_desc, fifo_getattr }, /* getattr */
46 { &vop_setattr_desc, fifo_setattr }, /* setattr */
47 { &vop_read_desc, fifo_read }, /* read */
48 { &vop_write_desc, fifo_write }, /* write */
49 { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */
50 { &vop_select_desc, fifo_select }, /* select */
51 { &vop_mmap_desc, fifo_mmap }, /* mmap */
52 { &vop_fsync_desc, fifo_fsync }, /* fsync */
53 { &vop_seek_desc, fifo_seek }, /* seek */
54 { &vop_remove_desc, fifo_remove }, /* remove */
55 { &vop_link_desc, fifo_link }, /* link */
56 { &vop_rename_desc, fifo_rename }, /* rename */
57 { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */
58 { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */
59 { &vop_symlink_desc, fifo_symlink }, /* symlink */
60 { &vop_readdir_desc, fifo_readdir }, /* readdir */
61 { &vop_readlink_desc, fifo_readlink }, /* readlink */
62 { &vop_abortop_desc, fifo_abortop }, /* abortop */
63 { &vop_inactive_desc, fifo_inactive }, /* inactive */
64 { &vop_reclaim_desc, fifo_reclaim }, /* reclaim */
65 { &vop_lock_desc, fifo_lock }, /* lock */
66 { &vop_unlock_desc, fifo_unlock }, /* unlock */
67 { &vop_bmap_desc, fifo_bmap }, /* bmap */
68 { &vop_strategy_desc, fifo_strategy }, /* strategy */
69 { &vop_print_desc, fifo_print }, /* print */
70 { &vop_islocked_desc, fifo_islocked }, /* islocked */
71 { &vop_advlock_desc, fifo_advlock }, /* advlock */
72 { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */
73 { &vop_vget_desc, fifo_vget }, /* vget */
74 { &vop_valloc_desc, fifo_valloc }, /* valloc */
75 { &vop_vfree_desc, fifo_vfree }, /* vfree */
76 { &vop_truncate_desc, fifo_truncate }, /* truncate */
77 { &vop_update_desc, fifo_update }, /* update */
78 { &vop_bwrite_desc, fifo_bwrite }, /* bwrite */
79 { (struct vnodeop_desc*)NULL, (int(*)())NULL }
cc6b488e 80};
9342689a
JH
81struct vnodeopv_desc fifo_vnodeop_opv_desc =
82 { &fifo_vnodeop_p, fifo_vnodeop_entries };
cc6b488e
KM
83
84/*
85 * Trivial lookup routine that always fails.
86 */
81b4c293 87/* ARGSUSED */
9342689a
JH
88fifo_lookup (ap)
89 struct vop_lookup_args *ap;
90#define dvp (ap->a_dvp)
91#define vpp (ap->a_vpp)
92#define cnp (ap->a_cnp)
cc6b488e 93{
085e9ab7
JH
94
95 *vpp = NULL;
cc6b488e
KM
96 return (ENOTDIR);
97}
9342689a
JH
98#undef dvp
99#undef vpp
100#undef cnp
cc6b488e
KM
101
102/*
103 * Open called to set up a new instance of a fifo or
104 * to find an active instance of a fifo.
105 */
106/* ARGSUSED */
9342689a
JH
107fifo_open (ap)
108 struct vop_open_args *ap;
109#define vp (ap->a_vp)
110#define mode (ap->a_mode)
111#define cred (ap->a_cred)
112#define p (ap->a_p)
cc6b488e 113{
9342689a
JH
114 USES_VOP_CLOSE;
115 USES_VOP_LOCK;
116 USES_VOP_UNLOCK;
cc6b488e
KM
117 register struct fifoinfo *fip;
118 struct socket *rso, *wso;
119 int error;
bcc829cc 120 static char openstr[] = "fifo";
cc6b488e
KM
121
122 if ((mode & (FREAD|FWRITE)) == (FREAD|FWRITE))
123 return (EINVAL);
124 if ((fip = vp->v_fifoinfo) == NULL) {
125 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
126 vp->v_fifoinfo = fip;
ed89f575
KM
127 if (error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0)) {
128 free(fip, M_VNODE);
129 vp->v_fifoinfo = NULL;
cc6b488e 130 return (error);
ed89f575 131 }
cc6b488e
KM
132 fip->fi_readsock = rso;
133 if (error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0)) {
134 (void)soclose(rso);
ed89f575
KM
135 free(fip, M_VNODE);
136 vp->v_fifoinfo = NULL;
cc6b488e
KM
137 return (error);
138 }
139 fip->fi_writesock = wso;
140 if (error = unp_connect2(wso, rso)) {
141 (void)soclose(wso);
142 (void)soclose(rso);
ed89f575
KM
143 free(fip, M_VNODE);
144 vp->v_fifoinfo = NULL;
cc6b488e
KM
145 return (error);
146 }
80c4c463 147 fip->fi_readers = fip->fi_writers = 0;
cc6b488e
KM
148 wso->so_state |= SS_CANTRCVMORE;
149 rso->so_state |= SS_CANTSENDMORE;
150 }
151 error = 0;
152 if (mode & FREAD) {
153 fip->fi_readers++;
154 if (fip->fi_readers == 1) {
155 fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
156 if (fip->fi_writers > 0)
157 wakeup((caddr_t)&fip->fi_writers);
158 }
159 if (mode & O_NONBLOCK)
160 return (0);
80c4c463
KM
161 while (fip->fi_writers == 0) {
162 VOP_UNLOCK(vp);
163 error = tsleep((caddr_t)&fip->fi_readers, PSOCK,
164 openstr, 0);
165 VOP_LOCK(vp);
166 if (error)
cc6b488e 167 break;
80c4c463 168 }
cc6b488e
KM
169 } else {
170 fip->fi_writers++;
171 if (fip->fi_readers == 0 && (mode & O_NONBLOCK)) {
172 error = ENXIO;
173 } else {
174 if (fip->fi_writers == 1) {
175 fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
176 if (fip->fi_readers > 0)
177 wakeup((caddr_t)&fip->fi_readers);
178 }
80c4c463
KM
179 while (fip->fi_readers == 0) {
180 VOP_UNLOCK(vp);
181 error = tsleep((caddr_t)&fip->fi_writers,
182 PSOCK, openstr, 0);
183 VOP_LOCK(vp);
184 if (error)
cc6b488e 185 break;
80c4c463 186 }
cc6b488e
KM
187 }
188 }
189 if (error)
9342689a 190 VOP_CLOSE(vp, mode, cred, p);
cc6b488e
KM
191 return (error);
192}
9342689a
JH
193#undef vp
194#undef mode
195#undef cred
196#undef p
cc6b488e
KM
197
198/*
199 * Vnode op for read
200 */
201/* ARGSUSED */
9342689a
JH
202fifo_read (ap)
203 struct vop_read_args *ap;
204#define vp (ap->a_vp)
205#define uio (ap->a_uio)
206#define ioflag (ap->a_ioflag)
207#define cred (ap->a_cred)
cc6b488e 208{
9342689a
JH
209 USES_VOP_LOCK;
210 USES_VOP_UNLOCK;
cc6b488e
KM
211 register struct socket *rso = vp->v_fifoinfo->fi_readsock;
212 int error, startresid;
213
81b4c293 214#ifdef DIAGNOSTIC
cc6b488e
KM
215 if (uio->uio_rw != UIO_READ)
216 panic("fifo_read mode");
81b4c293 217#endif
cc6b488e
KM
218 if (uio->uio_resid == 0)
219 return (0);
220 if (ioflag & IO_NDELAY)
221 rso->so_state |= SS_NBIO;
222 startresid = uio->uio_resid;
223 VOP_UNLOCK(vp);
224 error = soreceive(rso, (struct mbuf **)0, uio, (int *)0,
225 (struct mbuf **)0, (struct mbuf **)0);
226 VOP_LOCK(vp);
227 /*
228 * Clear EOF indication after first such return.
229 */
230 if (uio->uio_resid == startresid)
231 rso->so_state &= ~SS_CANTRCVMORE;
232 if (ioflag & IO_NDELAY)
233 rso->so_state &= ~SS_NBIO;
234 return (error);
235}
9342689a
JH
236#undef vp
237#undef uio
238#undef ioflag
239#undef cred
cc6b488e
KM
240
241/*
242 * Vnode op for write
243 */
244/* ARGSUSED */
9342689a
JH
245fifo_write (ap)
246 struct vop_write_args *ap;
247#define vp (ap->a_vp)
248#define uio (ap->a_uio)
249#define ioflag (ap->a_ioflag)
250#define cred (ap->a_cred)
cc6b488e 251{
9342689a
JH
252 USES_VOP_LOCK;
253 USES_VOP_UNLOCK;
cc6b488e
KM
254 struct socket *wso = vp->v_fifoinfo->fi_writesock;
255 int error;
256
81b4c293 257#ifdef DIAGNOSTIC
cc6b488e
KM
258 if (uio->uio_rw != UIO_WRITE)
259 panic("fifo_write mode");
81b4c293 260#endif
cc6b488e
KM
261 if (ioflag & IO_NDELAY)
262 wso->so_state |= SS_NBIO;
263 VOP_UNLOCK(vp);
4032098c 264 error = sosend(wso, (struct mbuf *)0, uio, 0, (struct mbuf *)0, 0);
cc6b488e
KM
265 VOP_LOCK(vp);
266 if (ioflag & IO_NDELAY)
267 wso->so_state &= ~SS_NBIO;
268 return (error);
269}
9342689a
JH
270#undef vp
271#undef uio
272#undef ioflag
273#undef cred
cc6b488e
KM
274
275/*
276 * Device ioctl operation.
277 */
278/* ARGSUSED */
9342689a
JH
279fifo_ioctl (ap)
280 struct vop_ioctl_args *ap;
281#define vp (ap->a_vp)
282#define com (ap->a_command)
283#define data (ap->a_data)
284#define fflag (ap->a_fflag)
285#define cred (ap->a_cred)
286#define p (ap->a_p)
cc6b488e
KM
287{
288 struct file filetmp;
289 int error;
290
291 if (com == FIONBIO)
292 return (0);
293 if (fflag & FREAD)
294 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_readsock;
295 else
296 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_writesock;
81b4c293 297 return (soo_ioctl(&filetmp, com, data, p));
cc6b488e 298}
9342689a
JH
299#undef vp
300#undef com
301#undef data
302#undef fflag
303#undef cred
304#undef p
cc6b488e
KM
305
306/* ARGSUSED */
9342689a
JH
307fifo_select (ap)
308 struct vop_select_args *ap;
309#define vp (ap->a_vp)
310#define which (ap->a_which)
311#define fflag (ap->a_fflags)
312#define cred (ap->a_cred)
313#define p (ap->a_p)
cc6b488e
KM
314{
315 struct file filetmp;
316 int error;
317
318 if (fflag & FREAD)
319 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_readsock;
320 else
321 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_writesock;
81b4c293 322 return (soo_select(&filetmp, which, p));
cc6b488e 323}
9342689a
JH
324#undef vp
325#undef which
326#undef fflag
327#undef cred
328#undef p
cc6b488e
KM
329
330/*
331 * This is a noop, simply returning what one has been given.
332 */
9342689a
JH
333fifo_bmap (ap)
334 struct vop_bmap_args *ap;
335#define vp (ap->a_vp)
336#define bn (ap->a_bn)
337#define vpp (ap->a_vpp)
338#define bnp (ap->a_bnp)
cc6b488e
KM
339{
340
341 if (vpp != NULL)
342 *vpp = vp;
343 if (bnp != NULL)
344 *bnp = bn;
345 return (0);
346}
9342689a
JH
347#undef vp
348#undef bn
349#undef vpp
350#undef bnp
cc6b488e
KM
351
352/*
353 * At the moment we do not do any locking.
354 */
355/* ARGSUSED */
9342689a
JH
356fifo_lock (ap)
357 struct vop_lock_args *ap;
358#define vp (ap->a_vp)
cc6b488e
KM
359{
360
361 return (0);
362}
9342689a 363#undef vp
cc6b488e
KM
364
365/* ARGSUSED */
9342689a
JH
366fifo_unlock (ap)
367 struct vop_unlock_args *ap;
368#define vp (ap->a_vp)
cc6b488e
KM
369{
370
371 return (0);
372}
9342689a 373#undef vp
cc6b488e
KM
374
375/*
376 * Device close routine
377 */
378/* ARGSUSED */
9342689a
JH
379fifo_close (ap)
380 struct vop_close_args *ap;
381#define vp (ap->a_vp)
382#define fflag (ap->a_fflag)
383#define cred (ap->a_cred)
384#define p (ap->a_p)
cc6b488e
KM
385{
386 register struct fifoinfo *fip = vp->v_fifoinfo;
387 int error1, error2;
388
389 if (fflag & FWRITE) {
390 fip->fi_writers--;
391 if (fip->fi_writers == 0)
392 socantrcvmore(fip->fi_readsock);
393 } else {
394 fip->fi_readers--;
395 if (fip->fi_readers == 0)
396 socantsendmore(fip->fi_writesock);
397 }
398 if (vp->v_usecount > 1)
399 return (0);
400 error1 = soclose(fip->fi_readsock);
401 error2 = soclose(fip->fi_writesock);
402 FREE(fip, M_VNODE);
403 vp->v_fifoinfo = NULL;
404 if (error1)
405 return (error1);
406 return (error2);
407}
9342689a
JH
408#undef vp
409#undef fflag
410#undef cred
411#undef p
cc6b488e
KM
412
413/*
414 * Print out the contents of a fifo vnode.
415 */
9342689a
JH
416fifo_print (ap)
417 struct vop_print_args *ap;
418#define vp (ap->a_vp)
cc6b488e
KM
419{
420
421 printf("tag VT_NON");
422 fifo_printinfo(vp);
423 printf("\n");
424}
9342689a 425#undef vp
cc6b488e
KM
426
427/*
428 * Print out internal contents of a fifo vnode.
429 */
430fifo_printinfo(vp)
431 struct vnode *vp;
432{
433 register struct fifoinfo *fip = vp->v_fifoinfo;
434
435 printf(", fifo with %d readers and %d writers",
436 fip->fi_readers, fip->fi_writers);
437}
438
439/*
440 * Fifo failed operation
441 */
442fifo_ebadf()
443{
444
445 return (EBADF);
446}
447
a4128336
KM
448/*
449 * Fifo advisory byte-level locks.
450 */
81b4c293 451/* ARGSUSED */
9342689a
JH
452fifo_advlock (ap)
453 struct vop_advlock_args *ap;
454#define vp (ap->a_vp)
455#define id (ap->a_id)
456#define op (ap->a_op)
457#define fl (ap->a_fl)
458#define flags (ap->a_flags)
a4128336
KM
459{
460
461 return (EOPNOTSUPP);
462}
9342689a
JH
463#undef vp
464#undef id
465#undef op
466#undef fl
467#undef flags
a4128336 468
cc6b488e
KM
469/*
470 * Fifo bad operation
471 */
472fifo_badop()
473{
474
475 panic("fifo_badop called");
476 /* NOTREACHED */
477}