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