xref: /original-bsd/sys/miscfs/deadfs/dead_vnops.c (revision 68d9582f)
1 /*
2  * Copyright (c) 1989 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)dead_vnops.c	7.21 (Berkeley) 05/31/92
8  */
9 
10 #include "param.h"
11 #include "systm.h"
12 #include "time.h"
13 #include "vnode.h"
14 #include "errno.h"
15 #include "namei.h"
16 #include "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_advlock ((int (*) __P((struct  vop_advlock_args *)))dead_ebadf)
56 #define dead_blkatoff ((int (*) __P((struct  vop_blkatoff_args *)))dead_badop)
57 #define dead_vget ((int (*) __P((struct  vop_vget_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_advlock_desc, dead_advlock },	/* advlock */
100 	{ &vop_blkatoff_desc, dead_blkatoff },	/* blkatoff */
101 	{ &vop_vget_desc, dead_vget },	/* vget */
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 *ap;
119 {
120 
121 	*ap->a_vpp = NULL;
122 	return (ENOTDIR);
123 }
124 
125 /*
126  * Open always fails as if device did not exist.
127  */
128 /* ARGSUSED */
129 dead_open (ap)
130 	struct vop_open_args *ap;
131 {
132 
133 	return (ENXIO);
134 }
135 
136 /*
137  * Vnode op for read
138  */
139 /* ARGSUSED */
140 dead_read (ap)
141 	struct vop_read_args *ap;
142 {
143 
144 	if (chkvnlock(ap->a_vp))
145 		panic("dead_read: lock");
146 	/*
147 	 * Return EOF for character devices, EIO for others
148 	 */
149 	if (ap->a_vp->v_type != VCHR)
150 		return (EIO);
151 	return (0);
152 }
153 
154 /*
155  * Vnode op for write
156  */
157 /* ARGSUSED */
158 dead_write (ap)
159 	struct vop_write_args *ap;
160 {
161 
162 	if (chkvnlock(ap->a_vp))
163 		panic("dead_write: lock");
164 	return (EIO);
165 }
166 
167 /*
168  * Device ioctl operation.
169  */
170 /* ARGSUSED */
171 dead_ioctl (ap)
172 	struct vop_ioctl_args *ap;
173 {
174 	USES_VOP_IOCTL;
175 
176 	if (!chkvnlock(ap->a_vp))
177 		return (EBADF);
178 	return (VCALL(ap->a_vp, VOFFSET(vop_ioctl), ap));
179 }
180 
181 /* ARGSUSED */
182 dead_select (ap)
183 	struct vop_select_args *ap;
184 {
185 
186 	/*
187 	 * Let the user find out that the descriptor is gone.
188 	 */
189 	return (1);
190 }
191 
192 /*
193  * Just call the device strategy routine
194  */
195 dead_strategy (ap)
196 	struct vop_strategy_args *ap;
197 {
198 	USES_VOP_STRATEGY;
199 
200 	if (ap->a_bp->b_vp == NULL || !chkvnlock(ap->a_bp->b_vp)) {
201 		ap->a_bp->b_flags |= B_ERROR;
202 		biodone(ap->a_bp);
203 		return (EIO);
204 	}
205 	return (VOP_STRATEGY(ap->a_bp));
206 }
207 
208 /*
209  * Wait until the vnode has finished changing state.
210  */
211 dead_lock (ap)
212 	struct vop_lock_args *ap;
213 {
214 	USES_VOP_LOCK;
215 
216 	if (!chkvnlock(ap->a_vp))
217 		return (0);
218 	return (VCALL(ap->a_vp, VOFFSET(vop_lock), ap));
219 }
220 
221 /*
222  * Wait until the vnode has finished changing state.
223  */
224 dead_bmap (ap)
225 	struct vop_bmap_args *ap;
226 {
227 	USES_VOP_BMAP;
228 
229 	if (!chkvnlock(ap->a_vp))
230 		return (EIO);
231 	return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp));
232 }
233 
234 /*
235  * Print out the contents of a dead vnode.
236  */
237 /* ARGSUSED */
238 dead_print (ap)
239 	struct vop_print_args *ap;
240 {
241 
242 	printf("tag VT_NON, dead vnode\n");
243 }
244 
245 /*
246  * Empty vnode failed operation
247  */
248 dead_ebadf()
249 {
250 
251 	return (EBADF);
252 }
253 
254 /*
255  * Empty vnode bad operation
256  */
257 dead_badop()
258 {
259 
260 	panic("dead_badop called");
261 	/* NOTREACHED */
262 }
263 
264 /*
265  * Empty vnode null operation
266  */
267 dead_nullop()
268 {
269 
270 	return (0);
271 }
272 
273 /*
274  * We have to wait during times when the vnode is
275  * in a state of change.
276  */
277 chkvnlock(vp)
278 	register struct vnode *vp;
279 {
280 	int locked = 0;
281 
282 	while (vp->v_flag & VXLOCK) {
283 		vp->v_flag |= VXWANT;
284 		sleep((caddr_t)vp, PINOD);
285 		locked = 1;
286 	}
287 	return (locked);
288 }
289