no longer pass proc to vn_open (now in ndp)
[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 *
ffcee610 7 * @(#)fifo_vnops.c 7.8 (Berkeley) %G%
cc6b488e
KM
8 */
9
10#include "param.h"
11#include "time.h"
12#include "namei.h"
13#include "vnode.h"
14#include "socket.h"
15#include "socketvar.h"
16#include "stat.h"
8429d022 17#include "systm.h"
cc6b488e
KM
18#include "ioctl.h"
19#include "file.h"
81b4c293 20#include "fifo.h"
cc6b488e
KM
21#include "errno.h"
22#include "malloc.h"
23
24/*
25 * This structure is associated with the FIFO vnode and stores
26 * the state associated with the FIFO.
27 */
28struct fifoinfo {
29 struct socket *fi_readsock;
30 struct socket *fi_writesock;
31 long fi_readers;
32 long fi_writers;
33};
34
cc6b488e
KM
35struct vnodeops fifo_vnodeops = {
36 fifo_lookup, /* lookup */
81b4c293
KM
37 fifo_create, /* create */
38 fifo_mknod, /* mknod */
cc6b488e
KM
39 fifo_open, /* open */
40 fifo_close, /* close */
81b4c293
KM
41 fifo_access, /* access */
42 fifo_getattr, /* getattr */
43 fifo_setattr, /* setattr */
cc6b488e
KM
44 fifo_read, /* read */
45 fifo_write, /* write */
46 fifo_ioctl, /* ioctl */
47 fifo_select, /* select */
81b4c293
KM
48 fifo_mmap, /* mmap */
49 fifo_fsync, /* fsync */
50 fifo_seek, /* seek */
51 fifo_remove, /* remove */
52 fifo_link, /* link */
53 fifo_rename, /* rename */
54 fifo_mkdir, /* mkdir */
55 fifo_rmdir, /* rmdir */
56 fifo_symlink, /* symlink */
57 fifo_readdir, /* readdir */
58 fifo_readlink, /* readlink */
59 fifo_abortop, /* abortop */
60 fifo_inactive, /* inactive */
61 fifo_reclaim, /* reclaim */
cc6b488e
KM
62 fifo_lock, /* lock */
63 fifo_unlock, /* unlock */
64 fifo_bmap, /* bmap */
81b4c293 65 fifo_strategy, /* strategy */
cc6b488e 66 fifo_print, /* print */
81b4c293 67 fifo_islocked, /* islocked */
a4128336 68 fifo_advlock, /* advlock */
ffcee610
KM
69 fifo_blkatoff, /* blkatoff */
70 fifo_vget, /* vget */
71 fifo_valloc, /* valloc */
72 fifo_vfree, /* vfree */
73 fifo_truncate, /* truncate */
74 fifo_update, /* update */
75 fifo_bwrite, /* bwrite */
cc6b488e
KM
76};
77
78/*
79 * Trivial lookup routine that always fails.
80 */
81b4c293
KM
81/* ARGSUSED */
82fifo_lookup(vp, ndp, p)
cc6b488e
KM
83 struct vnode *vp;
84 struct nameidata *ndp;
81b4c293 85 struct proc *p;
cc6b488e
KM
86{
87
88 ndp->ni_dvp = vp;
89 ndp->ni_vp = NULL;
90 return (ENOTDIR);
91}
92
93/*
94 * Open called to set up a new instance of a fifo or
95 * to find an active instance of a fifo.
96 */
97/* ARGSUSED */
81b4c293 98fifo_open(vp, mode, cred, p)
cc6b488e
KM
99 register struct vnode *vp;
100 int mode;
101 struct ucred *cred;
81b4c293 102 struct proc *p;
cc6b488e
KM
103{
104 register struct fifoinfo *fip;
105 struct socket *rso, *wso;
106 int error;
bcc829cc 107 static char openstr[] = "fifo";
cc6b488e
KM
108
109 if ((mode & (FREAD|FWRITE)) == (FREAD|FWRITE))
110 return (EINVAL);
111 if ((fip = vp->v_fifoinfo) == NULL) {
112 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
113 vp->v_fifoinfo = fip;
ed89f575
KM
114 if (error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0)) {
115 free(fip, M_VNODE);
116 vp->v_fifoinfo = NULL;
cc6b488e 117 return (error);
ed89f575 118 }
cc6b488e
KM
119 fip->fi_readsock = rso;
120 if (error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0)) {
121 (void)soclose(rso);
ed89f575
KM
122 free(fip, M_VNODE);
123 vp->v_fifoinfo = NULL;
cc6b488e
KM
124 return (error);
125 }
126 fip->fi_writesock = wso;
127 if (error = unp_connect2(wso, rso)) {
128 (void)soclose(wso);
129 (void)soclose(rso);
ed89f575
KM
130 free(fip, M_VNODE);
131 vp->v_fifoinfo = NULL;
cc6b488e
KM
132 return (error);
133 }
134 wso->so_state |= SS_CANTRCVMORE;
135 rso->so_state |= SS_CANTSENDMORE;
136 }
137 error = 0;
138 if (mode & FREAD) {
139 fip->fi_readers++;
140 if (fip->fi_readers == 1) {
141 fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
142 if (fip->fi_writers > 0)
143 wakeup((caddr_t)&fip->fi_writers);
144 }
145 if (mode & O_NONBLOCK)
146 return (0);
147 while (fip->fi_writers == 0)
bcc829cc
MK
148 if (error = tsleep((caddr_t)&fip->fi_readers, PSOCK,
149 openstr, 0))
cc6b488e
KM
150 break;
151 } else {
152 fip->fi_writers++;
153 if (fip->fi_readers == 0 && (mode & O_NONBLOCK)) {
154 error = ENXIO;
155 } else {
156 if (fip->fi_writers == 1) {
157 fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
158 if (fip->fi_readers > 0)
159 wakeup((caddr_t)&fip->fi_readers);
160 }
161 while (fip->fi_readers == 0)
bcc829cc
MK
162 if (error = tsleep((caddr_t)&fip->fi_writers,
163 PSOCK, openstr, 0))
cc6b488e
KM
164 break;
165 }
166 }
167 if (error)
81b4c293 168 fifo_close(vp, mode, cred, p);
cc6b488e
KM
169 return (error);
170}
171
172/*
173 * Vnode op for read
174 */
175/* ARGSUSED */
176fifo_read(vp, uio, ioflag, cred)
177 struct vnode *vp;
178 register struct uio *uio;
179 int ioflag;
180 struct ucred *cred;
181{
182 register struct socket *rso = vp->v_fifoinfo->fi_readsock;
183 int error, startresid;
184
81b4c293 185#ifdef DIAGNOSTIC
cc6b488e
KM
186 if (uio->uio_rw != UIO_READ)
187 panic("fifo_read mode");
81b4c293 188#endif
cc6b488e
KM
189 if (uio->uio_resid == 0)
190 return (0);
191 if (ioflag & IO_NDELAY)
192 rso->so_state |= SS_NBIO;
193 startresid = uio->uio_resid;
194 VOP_UNLOCK(vp);
195 error = soreceive(rso, (struct mbuf **)0, uio, (int *)0,
196 (struct mbuf **)0, (struct mbuf **)0);
197 VOP_LOCK(vp);
198 /*
199 * Clear EOF indication after first such return.
200 */
201 if (uio->uio_resid == startresid)
202 rso->so_state &= ~SS_CANTRCVMORE;
203 if (ioflag & IO_NDELAY)
204 rso->so_state &= ~SS_NBIO;
205 return (error);
206}
207
208/*
209 * Vnode op for write
210 */
211/* ARGSUSED */
212fifo_write(vp, uio, ioflag, cred)
213 struct vnode *vp;
214 register struct uio *uio;
215 int ioflag;
216 struct ucred *cred;
217{
218 struct socket *wso = vp->v_fifoinfo->fi_writesock;
219 int error;
220
81b4c293 221#ifdef DIAGNOSTIC
cc6b488e
KM
222 if (uio->uio_rw != UIO_WRITE)
223 panic("fifo_write mode");
81b4c293 224#endif
cc6b488e
KM
225 if (ioflag & IO_NDELAY)
226 wso->so_state |= SS_NBIO;
227 VOP_UNLOCK(vp);
228 error = sosend(wso, (struct mbuf *)0, uio, 0, (struct mbuf *)0);
229 VOP_LOCK(vp);
230 if (ioflag & IO_NDELAY)
231 wso->so_state &= ~SS_NBIO;
232 return (error);
233}
234
235/*
236 * Device ioctl operation.
237 */
238/* ARGSUSED */
81b4c293 239fifo_ioctl(vp, com, data, fflag, cred, p)
cc6b488e
KM
240 struct vnode *vp;
241 int com;
242 caddr_t data;
243 int fflag;
244 struct ucred *cred;
81b4c293 245 struct proc *p;
cc6b488e
KM
246{
247 struct file filetmp;
248 int error;
249
250 if (com == FIONBIO)
251 return (0);
252 if (fflag & FREAD)
253 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_readsock;
254 else
255 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_writesock;
81b4c293 256 return (soo_ioctl(&filetmp, com, data, p));
cc6b488e
KM
257}
258
259/* ARGSUSED */
81b4c293 260fifo_select(vp, which, fflag, cred, p)
cc6b488e
KM
261 struct vnode *vp;
262 int which, fflag;
263 struct ucred *cred;
81b4c293 264 struct proc *p;
cc6b488e
KM
265{
266 struct file filetmp;
267 int error;
268
269 if (fflag & FREAD)
270 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_readsock;
271 else
272 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_writesock;
81b4c293 273 return (soo_select(&filetmp, which, p));
cc6b488e
KM
274}
275
276/*
277 * This is a noop, simply returning what one has been given.
278 */
279fifo_bmap(vp, bn, vpp, bnp)
280 struct vnode *vp;
281 daddr_t bn;
282 struct vnode **vpp;
283 daddr_t *bnp;
284{
285
286 if (vpp != NULL)
287 *vpp = vp;
288 if (bnp != NULL)
289 *bnp = bn;
290 return (0);
291}
292
293/*
294 * At the moment we do not do any locking.
295 */
296/* ARGSUSED */
297fifo_lock(vp)
298 struct vnode *vp;
299{
300
301 return (0);
302}
303
304/* ARGSUSED */
305fifo_unlock(vp)
306 struct vnode *vp;
307{
308
309 return (0);
310}
311
312/*
313 * Device close routine
314 */
315/* ARGSUSED */
81b4c293 316fifo_close(vp, fflag, cred, p)
cc6b488e
KM
317 register struct vnode *vp;
318 int fflag;
319 struct ucred *cred;
81b4c293 320 struct proc *p;
cc6b488e
KM
321{
322 register struct fifoinfo *fip = vp->v_fifoinfo;
323 int error1, error2;
324
325 if (fflag & FWRITE) {
326 fip->fi_writers--;
327 if (fip->fi_writers == 0)
328 socantrcvmore(fip->fi_readsock);
329 } else {
330 fip->fi_readers--;
331 if (fip->fi_readers == 0)
332 socantsendmore(fip->fi_writesock);
333 }
334 if (vp->v_usecount > 1)
335 return (0);
336 error1 = soclose(fip->fi_readsock);
337 error2 = soclose(fip->fi_writesock);
338 FREE(fip, M_VNODE);
339 vp->v_fifoinfo = NULL;
340 if (error1)
341 return (error1);
342 return (error2);
343}
344
345/*
346 * Print out the contents of a fifo vnode.
347 */
348fifo_print(vp)
349 struct vnode *vp;
350{
351
352 printf("tag VT_NON");
353 fifo_printinfo(vp);
354 printf("\n");
355}
356
357/*
358 * Print out internal contents of a fifo vnode.
359 */
360fifo_printinfo(vp)
361 struct vnode *vp;
362{
363 register struct fifoinfo *fip = vp->v_fifoinfo;
364
365 printf(", fifo with %d readers and %d writers",
366 fip->fi_readers, fip->fi_writers);
367}
368
369/*
370 * Fifo failed operation
371 */
372fifo_ebadf()
373{
374
375 return (EBADF);
376}
377
a4128336
KM
378/*
379 * Fifo advisory byte-level locks.
380 */
81b4c293 381/* ARGSUSED */
a4128336
KM
382fifo_advlock(vp, id, op, fl, flags)
383 struct vnode *vp;
384 caddr_t id;
385 int op;
386 struct flock *fl;
387 int flags;
388{
389
390 return (EOPNOTSUPP);
391}
392
cc6b488e
KM
393/*
394 * Fifo bad operation
395 */
396fifo_badop()
397{
398
399 panic("fifo_badop called");
400 /* NOTREACHED */
401}