386BSD 0.1 development
[unix-history] / usr / src / sys.386bsd / kern / dead_vnops.c
CommitLineData
b688fc87
WJ
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * 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. 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.
20 *
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
31 * SUCH DAMAGE.
32 *
33 * @(#)dead_vnops.c 7.13 (Berkeley) 4/15/91
34 */
35
36#include "param.h"
37#include "systm.h"
38#include "time.h"
39#include "vnode.h"
40#include "errno.h"
41#include "namei.h"
42#include "buf.h"
43
44/*
45 * Prototypes for dead operations on vnodes.
46 */
47int dead_badop(),
48 dead_ebadf();
49int dead_lookup __P((
50 struct vnode *vp,
51 struct nameidata *ndp,
52 struct proc *p));
53#define dead_create ((int (*) __P(( \
54 struct nameidata *ndp, \
55 struct vattr *vap, \
56 struct proc *p))) dead_badop)
57#define dead_mknod ((int (*) __P(( \
58 struct nameidata *ndp, \
59 struct vattr *vap, \
60 struct ucred *cred, \
61 struct proc *p))) dead_badop)
62int dead_open __P((
63 struct vnode *vp,
64 int mode,
65 struct ucred *cred,
66 struct proc *p));
67#define dead_close ((int (*) __P(( \
68 struct vnode *vp, \
69 int fflag, \
70 struct ucred *cred, \
71 struct proc *p))) nullop)
72#define dead_access ((int (*) __P(( \
73 struct vnode *vp, \
74 int mode, \
75 struct ucred *cred, \
76 struct proc *p))) dead_ebadf)
77#define dead_getattr ((int (*) __P(( \
78 struct vnode *vp, \
79 struct vattr *vap, \
80 struct ucred *cred, \
81 struct proc *p))) dead_ebadf)
82#define dead_setattr ((int (*) __P(( \
83 struct vnode *vp, \
84 struct vattr *vap, \
85 struct ucred *cred, \
86 struct proc *p))) dead_ebadf)
87int dead_read __P((
88 struct vnode *vp,
89 struct uio *uio,
90 int ioflag,
91 struct ucred *cred));
92int dead_write __P((
93 struct vnode *vp,
94 struct uio *uio,
95 int ioflag,
96 struct ucred *cred));
97int dead_ioctl __P((
98 struct vnode *vp,
99 int command,
100 caddr_t data,
101 int fflag,
102 struct ucred *cred,
103 struct proc *p));
104int dead_select __P((
105 struct vnode *vp,
106 int which,
107 int fflags,
108 struct ucred *cred,
109 struct proc *p));
110#define dead_mmap ((int (*) __P(( \
111 struct vnode *vp, \
112 int fflags, \
113 struct ucred *cred, \
114 struct proc *p))) dead_badop)
115#define dead_fsync ((int (*) __P(( \
116 struct vnode *vp, \
117 int fflags, \
118 struct ucred *cred, \
119 int waitfor, \
120 struct proc *p))) nullop)
121#define dead_seek ((int (*) __P(( \
122 struct vnode *vp, \
123 off_t oldoff, \
124 off_t newoff, \
125 struct ucred *cred))) nullop)
126#define dead_remove ((int (*) __P(( \
127 struct nameidata *ndp, \
128 struct proc *p))) dead_badop)
129#define dead_link ((int (*) __P(( \
130 struct vnode *vp, \
131 struct nameidata *ndp, \
132 struct proc *p))) dead_badop)
133#define dead_rename ((int (*) __P(( \
134 struct nameidata *fndp, \
135 struct nameidata *tdnp, \
136 struct proc *p))) dead_badop)
137#define dead_mkdir ((int (*) __P(( \
138 struct nameidata *ndp, \
139 struct vattr *vap, \
140 struct proc *p))) dead_badop)
141#define dead_rmdir ((int (*) __P(( \
142 struct nameidata *ndp, \
143 struct proc *p))) dead_badop)
144#define dead_symlink ((int (*) __P(( \
145 struct nameidata *ndp, \
146 struct vattr *vap, \
147 char *target, \
148 struct proc *p))) dead_badop)
149#define dead_readdir ((int (*) __P(( \
150 struct vnode *vp, \
151 struct uio *uio, \
152 struct ucred *cred, \
153 int *eofflagp))) dead_ebadf)
154#define dead_readlink ((int (*) __P(( \
155 struct vnode *vp, \
156 struct uio *uio, \
157 struct ucred *cred))) dead_ebadf)
158#define dead_abortop ((int (*) __P(( \
159 struct nameidata *ndp))) dead_badop)
160#define dead_inactive ((int (*) __P(( \
161 struct vnode *vp, \
162 struct proc *p))) nullop)
163#define dead_reclaim ((int (*) __P(( \
164 struct vnode *vp))) nullop)
165int dead_lock __P((
166 struct vnode *vp));
167#define dead_unlock ((int (*) __P(( \
168 struct vnode *vp))) nullop)
169int dead_bmap __P((
170 struct vnode *vp,
171 daddr_t bn,
172 struct vnode **vpp,
173 daddr_t *bnp));
174int dead_strategy __P((
175 struct buf *bp));
176int dead_print __P((
177 struct vnode *vp));
178#define dead_islocked ((int (*) __P(( \
179 struct vnode *vp))) nullop)
180#define dead_advlock ((int (*) __P(( \
181 struct vnode *vp, \
182 caddr_t id, \
183 int op, \
184 struct flock *fl, \
185 int flags))) dead_ebadf)
186
187struct vnodeops dead_vnodeops = {
188 dead_lookup, /* lookup */
189 dead_create, /* create */
190 dead_mknod, /* mknod */
191 dead_open, /* open */
192 dead_close, /* close */
193 dead_access, /* access */
194 dead_getattr, /* getattr */
195 dead_setattr, /* setattr */
196 dead_read, /* read */
197 dead_write, /* write */
198 dead_ioctl, /* ioctl */
199 dead_select, /* select */
200 dead_mmap, /* mmap */
201 dead_fsync, /* fsync */
202 dead_seek, /* seek */
203 dead_remove, /* remove */
204 dead_link, /* link */
205 dead_rename, /* rename */
206 dead_mkdir, /* mkdir */
207 dead_rmdir, /* rmdir */
208 dead_symlink, /* symlink */
209 dead_readdir, /* readdir */
210 dead_readlink, /* readlink */
211 dead_abortop, /* abortop */
212 dead_inactive, /* inactive */
213 dead_reclaim, /* reclaim */
214 dead_lock, /* lock */
215 dead_unlock, /* unlock */
216 dead_bmap, /* bmap */
217 dead_strategy, /* strategy */
218 dead_print, /* print */
219 dead_islocked, /* islocked */
220 dead_advlock, /* advlock */
221};
222
223/*
224 * Trivial lookup routine that always fails.
225 */
226/* ARGSUSED */
227dead_lookup(vp, ndp, p)
228 struct vnode *vp;
229 struct nameidata *ndp;
230 struct proc *p;
231{
232
233 ndp->ni_dvp = vp;
234 ndp->ni_vp = NULL;
235 return (ENOTDIR);
236}
237
238/*
239 * Open always fails as if device did not exist.
240 */
241/* ARGSUSED */
242dead_open(vp, mode, cred, p)
243 struct vnode *vp;
244 int mode;
245 struct ucred *cred;
246 struct proc *p;
247{
248
249 return (ENXIO);
250}
251
252/*
253 * Vnode op for read
254 */
255/* ARGSUSED */
256dead_read(vp, uio, ioflag, cred)
257 struct vnode *vp;
258 struct uio *uio;
259 int ioflag;
260 struct ucred *cred;
261{
262
263 if (chkvnlock(vp))
264 panic("dead_read: lock");
265 /*
266 * Return EOF for character devices, EIO for others
267 */
268 if (vp->v_type != VCHR)
269 return (EIO);
270 return (0);
271}
272
273/*
274 * Vnode op for write
275 */
276/* ARGSUSED */
277dead_write(vp, uio, ioflag, cred)
278 register struct vnode *vp;
279 struct uio *uio;
280 int ioflag;
281 struct ucred *cred;
282{
283
284 if (chkvnlock(vp))
285 panic("dead_write: lock");
286 return (EIO);
287}
288
289/*
290 * Device ioctl operation.
291 */
292/* ARGSUSED */
293dead_ioctl(vp, com, data, fflag, cred, p)
294 struct vnode *vp;
295 register int com;
296 caddr_t data;
297 int fflag;
298 struct ucred *cred;
299 struct proc *p;
300{
301
302 if (!chkvnlock(vp))
303 return (EBADF);
304 return (VOP_IOCTL(vp, com, data, fflag, cred, p));
305}
306
307/* ARGSUSED */
308dead_select(vp, which, fflags, cred, p)
309 struct vnode *vp;
310 int which, fflags;
311 struct ucred *cred;
312 struct proc *p;
313{
314
315 /*
316 * Let the user find out that the descriptor is gone.
317 */
318 return (1);
319}
320
321/*
322 * Just call the device strategy routine
323 */
324dead_strategy(bp)
325 register struct buf *bp;
326{
327
328 if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) {
329 bp->b_flags |= B_ERROR;
330 biodone(bp);
331 return (EIO);
332 }
333 return (VOP_STRATEGY(bp));
334}
335
336/*
337 * Wait until the vnode has finished changing state.
338 */
339dead_lock(vp)
340 struct vnode *vp;
341{
342
343 if (!chkvnlock(vp))
344 return (0);
345 return (VOP_LOCK(vp));
346}
347
348/*
349 * Wait until the vnode has finished changing state.
350 */
351dead_bmap(vp, bn, vpp, bnp)
352 struct vnode *vp;
353 daddr_t bn;
354 struct vnode **vpp;
355 daddr_t *bnp;
356{
357
358 if (!chkvnlock(vp))
359 return (EIO);
360 return (VOP_BMAP(vp, bn, vpp, bnp));
361}
362
363/*
364 * Print out the contents of a dead vnode.
365 */
366/* ARGSUSED */
367dead_print(vp)
368 struct vnode *vp;
369{
370
371 printf("tag VT_NON, dead vnode\n");
372}
373
374/*
375 * Empty vnode failed operation
376 */
377dead_ebadf()
378{
379
380 return (EBADF);
381}
382
383/*
384 * Empty vnode bad operation
385 */
386dead_badop()
387{
388
389 panic("dead_badop called");
390 /* NOTREACHED */
391}
392
393/*
394 * Empty vnode null operation
395 */
396dead_nullop()
397{
398
399 return (0);
400}
401
402/*
403 * We have to wait during times when the vnode is
404 * in a state of change.
405 */
406chkvnlock(vp)
407 register struct vnode *vp;
408{
409 int locked = 0;
410
411 while (vp->v_flag & VXLOCK) {
412 vp->v_flag |= VXWANT;
413 sleep((caddr_t)vp, PINOD);
414 locked = 1;
415 }
416 return (locked);
417}