dead_vnops.c revision 1.54 1 /* $NetBSD: dead_vnops.c,v 1.54 2014/02/07 15:29:22 hannken Exp $ */
2
3 /*
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)dead_vnops.c 8.2 (Berkeley) 11/21/94
32 */
33
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: dead_vnops.c,v 1.54 2014/02/07 15:29:22 hannken Exp $");
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/time.h>
40 #include <sys/vnode.h>
41 #include <sys/errno.h>
42 #include <sys/namei.h>
43 #include <sys/buf.h>
44 #include <sys/proc.h>
45
46 #include <miscfs/genfs/genfs.h>
47
48 /*
49 * Prototypes for dead operations on vnodes.
50 */
51 #define dead_bwrite genfs_nullop
52 int dead_lookup(void *);
53 int dead_open(void *);
54 #define dead_close genfs_nullop
55 int dead_read(void *);
56 int dead_write(void *);
57 #define dead_fcntl genfs_nullop
58 int dead_ioctl(void *);
59 int dead_poll(void *);
60 int dead_remove(void *);
61 int dead_link(void *);
62 int dead_rename(void *);
63 int dead_rmdir(void *);
64 #define dead_fsync genfs_nullop
65 #define dead_seek genfs_nullop
66 int dead_inactive(void *);
67 #define dead_reclaim genfs_nullop
68 #define dead_lock genfs_lock
69 #define dead_unlock genfs_unlock
70 int dead_bmap(void *);
71 int dead_strategy(void *);
72 int dead_print(void *);
73 #define dead_islocked genfs_islocked
74 #define dead_revoke genfs_nullop
75 int dead_getpages(void *);
76 int dead_putpages(void *);
77
78 int dead_default_error(void *);
79
80 int (**dead_vnodeop_p)(void *);
81
82 const struct vnodeopv_entry_desc dead_vnodeop_entries[] = {
83 { &vop_default_desc, dead_default_error },
84 { &vop_bwrite_desc, dead_bwrite }, /* bwrite */
85 { &vop_lookup_desc, dead_lookup }, /* lookup */
86 { &vop_open_desc, dead_open }, /* open */
87 { &vop_close_desc, dead_close }, /* close */
88 { &vop_read_desc, dead_read }, /* read */
89 { &vop_write_desc, dead_write }, /* write */
90 { &vop_fcntl_desc, dead_fcntl }, /* fcntl */
91 { &vop_ioctl_desc, dead_ioctl }, /* ioctl */
92 { &vop_poll_desc, dead_poll }, /* poll */
93 { &vop_remove_desc, dead_remove }, /* remove */
94 { &vop_link_desc, dead_link }, /* link */
95 { &vop_rename_desc, dead_rename }, /* rename */
96 { &vop_rmdir_desc, dead_rmdir }, /* rmdir */
97 { &vop_fsync_desc, dead_fsync }, /* fsync */
98 { &vop_seek_desc, dead_seek }, /* seek */
99 { &vop_inactive_desc, dead_inactive }, /* inactive */
100 { &vop_reclaim_desc, dead_reclaim }, /* reclaim */
101 { &vop_lock_desc, dead_lock }, /* lock */
102 { &vop_unlock_desc, dead_unlock }, /* unlock */
103 { &vop_bmap_desc, dead_bmap }, /* bmap */
104 { &vop_strategy_desc, dead_strategy }, /* strategy */
105 { &vop_print_desc, dead_print }, /* print */
106 { &vop_islocked_desc, dead_islocked }, /* islocked */
107 { &vop_revoke_desc, dead_revoke }, /* revoke */
108 { &vop_getpages_desc, dead_getpages }, /* getpages */
109 { &vop_putpages_desc, dead_putpages }, /* putpages */
110 { NULL, NULL }
111 };
112 const struct vnodeopv_desc dead_vnodeop_opv_desc =
113 { &dead_vnodeop_p, dead_vnodeop_entries };
114
115 /* ARGSUSED */
116 int
117 dead_default_error(void *v)
118 {
119
120 return EBADF;
121 }
122
123 /* ARGSUSED */
124 int
125 dead_bmap(void *v)
126 {
127 /* struct vop_bmap_args {
128 struct vnode *a_vp;
129 daddr_t a_bn;
130 struct vnode **a_vpp;
131 daddr_t *a_bnp;
132 int *a_runp;
133 } *ap = v; */
134
135 return (EIO);
136 }
137
138 int
139 dead_lookup(void *v)
140 {
141 struct vop_lookup_v2_args /* {
142 struct vnode *a_dvp;
143 struct vnode **a_vpp;
144 struct componentname *a_cnp;
145 } */ *ap = v;
146
147 *(ap->a_vpp) = NULL;
148
149 return EIO;
150 }
151
152 /* ARGSUSED */
153 int
154 dead_open(void *v)
155 {
156 /* struct vop_open_args {
157 struct vnode *a_vp;
158 int a_mode;
159 kauth_cred_t a_cred;
160 } *ap = v; */
161
162 return (ENXIO);
163 }
164
165 int
166 dead_read(void *v)
167 {
168 struct vop_read_args /* {
169 struct vnode *a_vp;
170 struct uio *a_uio;
171 int a_ioflag;
172 kauth_cred_t a_cred;
173 } */ *ap = v;
174
175 /*
176 * Return EOF for tty devices, EIO for others
177 */
178 if ((ap->a_vp->v_vflag & VV_ISTTY) == 0)
179 return (EIO);
180 return (0);
181 }
182
183 /* ARGSUSED */
184 int
185 dead_write(void *v)
186 {
187 /* struct vop_write_args {
188 struct vnode *a_vp;
189 struct uio *a_uio;
190 int a_ioflag;
191 kauth_cred_t a_cred;
192 } *ap = v; */
193
194 return (EIO);
195 }
196
197 /* ARGSUSED */
198 int
199 dead_ioctl(void *v)
200 {
201 /* struct vop_ioctl_args {
202 struct vnode *a_vp;
203 u_long a_command;
204 void *a_data;
205 int a_fflag;
206 kauth_cred_t a_cred;
207 struct lwp *a_l;
208 } *ap = v; */
209
210 return (EBADF);
211 }
212
213 int
214 dead_poll(void *v)
215 {
216 struct vop_poll_args /* {
217 struct vnode *a_vp;
218 int a_events;
219 struct lwp *a_l;
220 } */ *ap = v;
221
222 /*
223 * Let the user find out that the descriptor is gone.
224 */
225 return (ap->a_events);
226 }
227
228 int
229 dead_remove(void *v)
230 {
231 struct vop_remove_args /* {
232 struct vnode *a_dvp;
233 struct vnode *a_vp;
234 struct componentname *a_cnp;
235 } */ *ap = v;
236
237 vput(ap->a_dvp);
238 vput(ap->a_vp);
239
240 return EIO;
241 }
242
243 int
244 dead_link(void *v)
245 {
246 struct vop_link_args /* {
247 struct vnode *a_dvp;
248 struct vnode *a_vp;
249 struct componentname *a_cnp;
250 } */ *ap = v;
251
252 vput(ap->a_dvp);
253
254 return EIO;
255 }
256
257 int
258 dead_rename(void *v)
259 {
260 struct vop_rename_args /* {
261 struct vnode *a_fdvp;
262 struct vnode *a_fvp;
263 struct componentname *a_fcnp;
264 struct vnode *a_tdvp;
265 struct vnode *a_tvp;
266 struct componentname *a_tcnp;
267 } */ *ap = v;
268
269 vrele(ap->a_fdvp);
270 vrele(ap->a_fvp);
271 if (ap->a_tvp != NULL && ap->a_tvp != ap->a_tdvp)
272 VOP_UNLOCK(ap->a_tvp);
273 vput(ap->a_tdvp);
274 if (ap->a_tvp != NULL)
275 vrele(ap->a_tvp);
276
277 return EIO;
278 }
279
280 int
281 dead_rmdir(void *v)
282 {
283 struct vop_rmdir_args /* {
284 struct vnode *a_dvp;
285 struct vnode *a_vp;
286 struct componentname *a_cnp;
287 } */ *ap = v;
288
289 vput(ap->a_dvp);
290 vput(ap->a_vp);
291
292 return EIO;
293 }
294
295 int
296 dead_inactive(void *v)
297 {
298 struct vop_inactive_args /* {
299 struct vnode *a_vp;
300 bool *a_recycle;
301 } */ *ap = v;
302
303 *ap->a_recycle = false;
304 VOP_UNLOCK(ap->a_vp);
305
306 return 0;
307 }
308
309 int
310 dead_strategy(void *v)
311 {
312 struct vop_strategy_args /* {
313 struct vnode *a_vp;
314 struct buf *a_bp;
315 } */ *ap = v;
316 struct buf *bp;
317
318 bp = ap->a_bp;
319 bp->b_error = EIO;
320 bp->b_resid = bp->b_bcount;
321 biodone(ap->a_bp);
322 return (EIO);
323 }
324
325 /* ARGSUSED */
326 int
327 dead_print(void *v)
328 {
329 printf("tag VT_NON, dead vnode\n");
330 return 0;
331 }
332
333 int
334 dead_getpages(void *v)
335 {
336 struct vop_getpages_args /* {
337 struct vnode *a_vp;
338 voff_t a_offset;
339 struct vm_page **a_m;
340 int *a_count;
341 int a_centeridx;
342 vm_prot_t a_access_type;
343 int a_advice;
344 int a_flags;
345 } */ *ap = v;
346
347 if ((ap->a_flags & PGO_LOCKED) == 0)
348 mutex_exit(ap->a_vp->v_interlock);
349
350 return (EFAULT);
351 }
352
353 int
354 dead_putpages(void *v)
355 {
356 struct vop_putpages_args /* {
357 struct vnode *a_vp;
358 voff_t a_offlo;
359 voff_t a_offhi;
360 int a_flags;
361 } */ *ap = v;
362
363 mutex_exit(ap->a_vp->v_interlock);
364 return (EFAULT);
365 }
366