xref: /original-bsd/sys/miscfs/deadfs/dead_vnops.c (revision 0997b878)
1 /*
2  * Copyright (c) 1989, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)dead_vnops.c	8.2 (Berkeley) 11/21/94
8  */
9 
10 #include <sys/param.h>
11 #include <sys/systm.h>
12 #include <sys/time.h>
13 #include <sys/vnode.h>
14 #include <sys/errno.h>
15 #include <sys/namei.h>
16 #include <sys/buf.h>
17 
18 /*
19  * Prototypes for dead operations on vnodes.
20  */
21 int	dead_badop(),
22 	dead_ebadf();
23 int	dead_lookup __P((struct vop_lookup_args *));
24 #define dead_create ((int (*) __P((struct  vop_create_args *)))dead_badop)
25 #define dead_mknod ((int (*) __P((struct  vop_mknod_args *)))dead_badop)
26 int	dead_open __P((struct vop_open_args *));
27 #define dead_close ((int (*) __P((struct  vop_close_args *)))nullop)
28 #define dead_access ((int (*) __P((struct  vop_access_args *)))dead_ebadf)
29 #define dead_getattr ((int (*) __P((struct  vop_getattr_args *)))dead_ebadf)
30 #define dead_setattr ((int (*) __P((struct  vop_setattr_args *)))dead_ebadf)
31 int	dead_read __P((struct vop_read_args *));
32 int	dead_write __P((struct vop_write_args *));
33 int	dead_ioctl __P((struct vop_ioctl_args *));
34 int	dead_select __P((struct vop_select_args *));
35 #define dead_mmap ((int (*) __P((struct  vop_mmap_args *)))dead_badop)
36 #define dead_fsync ((int (*) __P((struct  vop_fsync_args *)))nullop)
37 #define dead_seek ((int (*) __P((struct  vop_seek_args *)))nullop)
38 #define dead_remove ((int (*) __P((struct  vop_remove_args *)))dead_badop)
39 #define dead_link ((int (*) __P((struct  vop_link_args *)))dead_badop)
40 #define dead_rename ((int (*) __P((struct  vop_rename_args *)))dead_badop)
41 #define dead_mkdir ((int (*) __P((struct  vop_mkdir_args *)))dead_badop)
42 #define dead_rmdir ((int (*) __P((struct  vop_rmdir_args *)))dead_badop)
43 #define dead_symlink ((int (*) __P((struct  vop_symlink_args *)))dead_badop)
44 #define dead_readdir ((int (*) __P((struct  vop_readdir_args *)))dead_ebadf)
45 #define dead_readlink ((int (*) __P((struct  vop_readlink_args *)))dead_ebadf)
46 #define dead_abortop ((int (*) __P((struct  vop_abortop_args *)))dead_badop)
47 #define dead_inactive ((int (*) __P((struct  vop_inactive_args *)))nullop)
48 #define dead_reclaim ((int (*) __P((struct  vop_reclaim_args *)))nullop)
49 int	dead_lock __P((struct vop_lock_args *));
50 #define dead_unlock ((int (*) __P((struct  vop_unlock_args *)))nullop)
51 int	dead_bmap __P((struct vop_bmap_args *));
52 int	dead_strategy __P((struct vop_strategy_args *));
53 int	dead_print __P((struct vop_print_args *));
54 #define dead_islocked ((int (*) __P((struct  vop_islocked_args *)))nullop)
55 #define dead_pathconf ((int (*) __P((struct  vop_pathconf_args *)))dead_ebadf)
56 #define dead_advlock ((int (*) __P((struct  vop_advlock_args *)))dead_ebadf)
57 #define dead_blkatoff ((int (*) __P((struct  vop_blkatoff_args *)))dead_badop)
58 #define dead_valloc ((int (*) __P((struct  vop_valloc_args *)))dead_badop)
59 #define dead_vfree ((int (*) __P((struct  vop_vfree_args *)))dead_badop)
60 #define dead_truncate ((int (*) __P((struct  vop_truncate_args *)))nullop)
61 #define dead_update ((int (*) __P((struct  vop_update_args *)))nullop)
62 #define dead_bwrite ((int (*) __P((struct  vop_bwrite_args *)))nullop)
63 
64 int (**dead_vnodeop_p)();
65 struct vnodeopv_entry_desc dead_vnodeop_entries[] = {
66 	{ &vop_default_desc, vn_default_error },
67 	{ &vop_lookup_desc, dead_lookup },	/* lookup */
68 	{ &vop_create_desc, dead_create },	/* create */
69 	{ &vop_mknod_desc, dead_mknod },	/* mknod */
70 	{ &vop_open_desc, dead_open },	/* open */
71 	{ &vop_close_desc, dead_close },	/* close */
72 	{ &vop_access_desc, dead_access },	/* access */
73 	{ &vop_getattr_desc, dead_getattr },	/* getattr */
74 	{ &vop_setattr_desc, dead_setattr },	/* setattr */
75 	{ &vop_read_desc, dead_read },	/* read */
76 	{ &vop_write_desc, dead_write },	/* write */
77 	{ &vop_ioctl_desc, dead_ioctl },	/* ioctl */
78 	{ &vop_select_desc, dead_select },	/* select */
79 	{ &vop_mmap_desc, dead_mmap },	/* mmap */
80 	{ &vop_fsync_desc, dead_fsync },	/* fsync */
81 	{ &vop_seek_desc, dead_seek },	/* seek */
82 	{ &vop_remove_desc, dead_remove },	/* remove */
83 	{ &vop_link_desc, dead_link },	/* link */
84 	{ &vop_rename_desc, dead_rename },	/* rename */
85 	{ &vop_mkdir_desc, dead_mkdir },	/* mkdir */
86 	{ &vop_rmdir_desc, dead_rmdir },	/* rmdir */
87 	{ &vop_symlink_desc, dead_symlink },	/* symlink */
88 	{ &vop_readdir_desc, dead_readdir },	/* readdir */
89 	{ &vop_readlink_desc, dead_readlink },	/* readlink */
90 	{ &vop_abortop_desc, dead_abortop },	/* abortop */
91 	{ &vop_inactive_desc, dead_inactive },	/* inactive */
92 	{ &vop_reclaim_desc, dead_reclaim },	/* reclaim */
93 	{ &vop_lock_desc, dead_lock },	/* lock */
94 	{ &vop_unlock_desc, dead_unlock },	/* unlock */
95 	{ &vop_bmap_desc, dead_bmap },	/* bmap */
96 	{ &vop_strategy_desc, dead_strategy },	/* strategy */
97 	{ &vop_print_desc, dead_print },	/* print */
98 	{ &vop_islocked_desc, dead_islocked },	/* islocked */
99 	{ &vop_pathconf_desc, dead_pathconf },	/* pathconf */
100 	{ &vop_advlock_desc, dead_advlock },	/* advlock */
101 	{ &vop_blkatoff_desc, dead_blkatoff },	/* blkatoff */
102 	{ &vop_valloc_desc, dead_valloc },	/* valloc */
103 	{ &vop_vfree_desc, dead_vfree },	/* vfree */
104 	{ &vop_truncate_desc, dead_truncate },	/* truncate */
105 	{ &vop_update_desc, dead_update },	/* update */
106 	{ &vop_bwrite_desc, dead_bwrite },	/* bwrite */
107 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
108 };
109 struct vnodeopv_desc dead_vnodeop_opv_desc =
110 	{ &dead_vnodeop_p, dead_vnodeop_entries };
111 
112 /*
113  * Trivial lookup routine that always fails.
114  */
115 /* ARGSUSED */
116 int
117 dead_lookup(ap)
118 	struct vop_lookup_args /* {
119 		struct vnode * a_dvp;
120 		struct vnode ** a_vpp;
121 		struct componentname * a_cnp;
122 	} */ *ap;
123 {
124 
125 	*ap->a_vpp = NULL;
126 	return (ENOTDIR);
127 }
128 
129 /*
130  * Open always fails as if device did not exist.
131  */
132 /* ARGSUSED */
133 dead_open(ap)
134 	struct vop_open_args /* {
135 		struct vnode *a_vp;
136 		int  a_mode;
137 		struct ucred *a_cred;
138 		struct proc *a_p;
139 	} */ *ap;
140 {
141 
142 	return (ENXIO);
143 }
144 
145 /*
146  * Vnode op for read
147  */
148 /* ARGSUSED */
149 dead_read(ap)
150 	struct vop_read_args /* {
151 		struct vnode *a_vp;
152 		struct uio *a_uio;
153 		int  a_ioflag;
154 		struct ucred *a_cred;
155 	} */ *ap;
156 {
157 
158 	if (chkvnlock(ap->a_vp))
159 		panic("dead_read: lock");
160 	/*
161 	 * Return EOF for tty devices, EIO for others
162 	 */
163 	if ((ap->a_vp->v_flag & VISTTY) == 0)
164 		return (EIO);
165 	return (0);
166 }
167 
168 /*
169  * Vnode op for write
170  */
171 /* ARGSUSED */
172 dead_write(ap)
173 	struct vop_write_args /* {
174 		struct vnode *a_vp;
175 		struct uio *a_uio;
176 		int  a_ioflag;
177 		struct ucred *a_cred;
178 	} */ *ap;
179 {
180 
181 	if (chkvnlock(ap->a_vp))
182 		panic("dead_write: lock");
183 	return (EIO);
184 }
185 
186 /*
187  * Device ioctl operation.
188  */
189 /* ARGSUSED */
190 dead_ioctl(ap)
191 	struct vop_ioctl_args /* {
192 		struct vnode *a_vp;
193 		int  a_command;
194 		caddr_t  a_data;
195 		int  a_fflag;
196 		struct ucred *a_cred;
197 		struct proc *a_p;
198 	} */ *ap;
199 {
200 
201 	if (!chkvnlock(ap->a_vp))
202 		return (EBADF);
203 	return (VCALL(ap->a_vp, VOFFSET(vop_ioctl), ap));
204 }
205 
206 /* ARGSUSED */
207 dead_select(ap)
208 	struct vop_select_args /* {
209 		struct vnode *a_vp;
210 		int  a_which;
211 		int  a_fflags;
212 		struct ucred *a_cred;
213 		struct proc *a_p;
214 	} */ *ap;
215 {
216 
217 	/*
218 	 * Let the user find out that the descriptor is gone.
219 	 */
220 	return (1);
221 }
222 
223 /*
224  * Just call the device strategy routine
225  */
226 dead_strategy(ap)
227 	struct vop_strategy_args /* {
228 		struct buf *a_bp;
229 	} */ *ap;
230 {
231 
232 	if (ap->a_bp->b_vp == NULL || !chkvnlock(ap->a_bp->b_vp)) {
233 		ap->a_bp->b_flags |= B_ERROR;
234 		biodone(ap->a_bp);
235 		return (EIO);
236 	}
237 	return (VOP_STRATEGY(ap->a_bp));
238 }
239 
240 /*
241  * Wait until the vnode has finished changing state.
242  */
243 dead_lock(ap)
244 	struct vop_lock_args /* {
245 		struct vnode *a_vp;
246 	} */ *ap;
247 {
248 
249 	if (!chkvnlock(ap->a_vp))
250 		return (0);
251 	return (VCALL(ap->a_vp, VOFFSET(vop_lock), ap));
252 }
253 
254 /*
255  * Wait until the vnode has finished changing state.
256  */
257 dead_bmap(ap)
258 	struct vop_bmap_args /* {
259 		struct vnode *a_vp;
260 		daddr_t  a_bn;
261 		struct vnode **a_vpp;
262 		daddr_t *a_bnp;
263 		int *a_runp;
264 	} */ *ap;
265 {
266 
267 	if (!chkvnlock(ap->a_vp))
268 		return (EIO);
269 	return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp));
270 }
271 
272 /*
273  * Print out the contents of a dead vnode.
274  */
275 /* ARGSUSED */
276 dead_print(ap)
277 	struct vop_print_args /* {
278 		struct vnode *a_vp;
279 	} */ *ap;
280 {
281 
282 	printf("tag VT_NON, dead vnode\n");
283 }
284 
285 /*
286  * Empty vnode failed operation
287  */
288 dead_ebadf()
289 {
290 
291 	return (EBADF);
292 }
293 
294 /*
295  * Empty vnode bad operation
296  */
297 dead_badop()
298 {
299 
300 	panic("dead_badop called");
301 	/* NOTREACHED */
302 }
303 
304 /*
305  * Empty vnode null operation
306  */
307 dead_nullop()
308 {
309 
310 	return (0);
311 }
312 
313 /*
314  * We have to wait during times when the vnode is
315  * in a state of change.
316  */
317 chkvnlock(vp)
318 	register struct vnode *vp;
319 {
320 	int locked = 0;
321 
322 	while (vp->v_flag & VXLOCK) {
323 		vp->v_flag |= VXWANT;
324 		sleep((caddr_t)vp, PINOD);
325 		locked = 1;
326 	}
327 	return (locked);
328 }
329