dead_vnops.c revision 1.2 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.2 1993/05/20 02:54:09 cgd 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 int dead_badop(),
49 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 int 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
188 struct vnodeops dead_vnodeops = {
189 dead_lookup, /* lookup */
190 dead_create, /* create */
191 dead_mknod, /* mknod */
192 dead_open, /* open */
193 dead_close, /* close */
194 dead_access, /* access */
195 dead_getattr, /* getattr */
196 dead_setattr, /* setattr */
197 dead_read, /* read */
198 dead_write, /* write */
199 dead_ioctl, /* ioctl */
200 dead_select, /* select */
201 dead_mmap, /* mmap */
202 dead_fsync, /* fsync */
203 dead_seek, /* seek */
204 dead_remove, /* remove */
205 dead_link, /* link */
206 dead_rename, /* rename */
207 dead_mkdir, /* mkdir */
208 dead_rmdir, /* rmdir */
209 dead_symlink, /* symlink */
210 dead_readdir, /* readdir */
211 dead_readlink, /* readlink */
212 dead_abortop, /* abortop */
213 dead_inactive, /* inactive */
214 dead_reclaim, /* reclaim */
215 dead_lock, /* lock */
216 dead_unlock, /* unlock */
217 dead_bmap, /* bmap */
218 dead_strategy, /* strategy */
219 dead_print, /* print */
220 dead_islocked, /* islocked */
221 dead_advlock, /* advlock */
222 };
223
224 /*
225 * Trivial lookup routine that always fails.
226 */
227 /* ARGSUSED */
228 dead_lookup(vp, ndp, p)
229 struct vnode *vp;
230 struct nameidata *ndp;
231 struct proc *p;
232 {
233
234 ndp->ni_dvp = vp;
235 ndp->ni_vp = NULL;
236 return (ENOTDIR);
237 }
238
239 /*
240 * Open always fails as if device did not exist.
241 */
242 /* ARGSUSED */
243 dead_open(vp, mode, cred, p)
244 struct vnode *vp;
245 int mode;
246 struct ucred *cred;
247 struct proc *p;
248 {
249
250 return (ENXIO);
251 }
252
253 /*
254 * Vnode op for read
255 */
256 /* ARGSUSED */
257 dead_read(vp, uio, ioflag, cred)
258 struct vnode *vp;
259 struct uio *uio;
260 int ioflag;
261 struct ucred *cred;
262 {
263
264 if (chkvnlock(vp))
265 panic("dead_read: lock");
266 /*
267 * Return EOF for character devices, EIO for others
268 */
269 if (vp->v_type != VCHR)
270 return (EIO);
271 return (0);
272 }
273
274 /*
275 * Vnode op for write
276 */
277 /* ARGSUSED */
278 dead_write(vp, uio, ioflag, cred)
279 register struct vnode *vp;
280 struct uio *uio;
281 int ioflag;
282 struct ucred *cred;
283 {
284
285 if (chkvnlock(vp))
286 panic("dead_write: lock");
287 return (EIO);
288 }
289
290 /*
291 * Device ioctl operation.
292 */
293 /* ARGSUSED */
294 dead_ioctl(vp, com, data, fflag, cred, p)
295 struct vnode *vp;
296 register int com;
297 caddr_t data;
298 int fflag;
299 struct ucred *cred;
300 struct proc *p;
301 {
302
303 if (!chkvnlock(vp))
304 return (EBADF);
305 return (VOP_IOCTL(vp, com, data, fflag, cred, p));
306 }
307
308 /* ARGSUSED */
309 dead_select(vp, which, fflags, cred, p)
310 struct vnode *vp;
311 int which, fflags;
312 struct ucred *cred;
313 struct proc *p;
314 {
315
316 /*
317 * Let the user find out that the descriptor is gone.
318 */
319 return (1);
320 }
321
322 /*
323 * Just call the device strategy routine
324 */
325 dead_strategy(bp)
326 register struct buf *bp;
327 {
328
329 if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) {
330 bp->b_flags |= B_ERROR;
331 biodone(bp);
332 return (EIO);
333 }
334 return (VOP_STRATEGY(bp));
335 }
336
337 /*
338 * Wait until the vnode has finished changing state.
339 */
340 dead_lock(vp)
341 struct vnode *vp;
342 {
343
344 if (!chkvnlock(vp))
345 return (0);
346 return (VOP_LOCK(vp));
347 }
348
349 /*
350 * Wait until the vnode has finished changing state.
351 */
352 dead_bmap(vp, bn, vpp, bnp)
353 struct vnode *vp;
354 daddr_t bn;
355 struct vnode **vpp;
356 daddr_t *bnp;
357 {
358
359 if (!chkvnlock(vp))
360 return (EIO);
361 return (VOP_BMAP(vp, bn, vpp, bnp));
362 }
363
364 /*
365 * Print out the contents of a dead vnode.
366 */
367 /* ARGSUSED */
368 dead_print(vp)
369 struct vnode *vp;
370 {
371
372 printf("tag VT_NON, dead vnode\n");
373 }
374
375 /*
376 * Empty vnode failed operation
377 */
378 dead_ebadf()
379 {
380
381 return (EBADF);
382 }
383
384 /*
385 * Empty vnode bad operation
386 */
387 dead_badop()
388 {
389
390 panic("dead_badop called");
391 /* NOTREACHED */
392 }
393
394 /*
395 * Empty vnode null operation
396 */
397 dead_nullop()
398 {
399
400 return (0);
401 }
402
403 /*
404 * We have to wait during times when the vnode is
405 * in a state of change.
406 */
407 chkvnlock(vp)
408 register struct vnode *vp;
409 {
410 int locked = 0;
411
412 while (vp->v_flag & VXLOCK) {
413 vp->v_flag |= VXWANT;
414 sleep((caddr_t)vp, PINOD);
415 locked = 1;
416 }
417 return (locked);
418 }
419