1 | /* $NetBSD: dead_vnops.c,v 1.59 2015/04/20 23:30:58 riastradh 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.59 2015/04/20 23:30:58 riastradh 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_deadlock |
69 | #define dead_unlock genfs_deadunlock |
70 | int dead_bmap(void *); |
71 | int dead_strategy(void *); |
72 | int dead_print(void *); |
73 | #define dead_islocked genfs_deadislocked |
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_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ |
91 | { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ |
92 | { &vop_fcntl_desc, dead_fcntl }, /* fcntl */ |
93 | { &vop_ioctl_desc, dead_ioctl }, /* ioctl */ |
94 | { &vop_poll_desc, dead_poll }, /* poll */ |
95 | { &vop_remove_desc, dead_remove }, /* remove */ |
96 | { &vop_link_desc, dead_link }, /* link */ |
97 | { &vop_rename_desc, dead_rename }, /* rename */ |
98 | { &vop_rmdir_desc, dead_rmdir }, /* rmdir */ |
99 | { &vop_fsync_desc, dead_fsync }, /* fsync */ |
100 | { &vop_seek_desc, dead_seek }, /* seek */ |
101 | { &vop_inactive_desc, dead_inactive }, /* inactive */ |
102 | { &vop_reclaim_desc, dead_reclaim }, /* reclaim */ |
103 | { &vop_lock_desc, dead_lock }, /* lock */ |
104 | { &vop_unlock_desc, dead_unlock }, /* unlock */ |
105 | { &vop_bmap_desc, dead_bmap }, /* bmap */ |
106 | { &vop_strategy_desc, dead_strategy }, /* strategy */ |
107 | { &vop_print_desc, dead_print }, /* print */ |
108 | { &vop_islocked_desc, dead_islocked }, /* islocked */ |
109 | { &vop_revoke_desc, dead_revoke }, /* revoke */ |
110 | { &vop_getpages_desc, dead_getpages }, /* getpages */ |
111 | { &vop_putpages_desc, dead_putpages }, /* putpages */ |
112 | { NULL, NULL } |
113 | }; |
114 | const struct vnodeopv_desc dead_vnodeop_opv_desc = |
115 | { &dead_vnodeop_p, dead_vnodeop_entries }; |
116 | |
117 | /* ARGSUSED */ |
118 | int |
119 | dead_default_error(void *v) |
120 | { |
121 | |
122 | return EBADF; |
123 | } |
124 | |
125 | int |
126 | dead_bmap(void *v) |
127 | { |
128 | struct vop_bmap_args /* { |
129 | struct vnode *a_vp; |
130 | daddr_t a_bn; |
131 | struct vnode **a_vpp; |
132 | daddr_t *a_bnp; |
133 | int *a_runp; |
134 | } */ *ap = v; |
135 | |
136 | (void)ap; |
137 | |
138 | return (EIO); |
139 | } |
140 | |
141 | int |
142 | dead_lookup(void *v) |
143 | { |
144 | struct vop_lookup_v2_args /* { |
145 | struct vnode *a_dvp; |
146 | struct vnode **a_vpp; |
147 | struct componentname *a_cnp; |
148 | } */ *ap = v; |
149 | |
150 | *(ap->a_vpp) = NULL; |
151 | |
152 | return ENOENT; |
153 | } |
154 | |
155 | int |
156 | dead_open(void *v) |
157 | { |
158 | struct vop_open_args /* { |
159 | struct vnode *a_vp; |
160 | int a_mode; |
161 | kauth_cred_t a_cred; |
162 | } */ *ap = v; |
163 | |
164 | (void)ap; |
165 | |
166 | return (ENXIO); |
167 | } |
168 | |
169 | int |
170 | dead_read(void *v) |
171 | { |
172 | struct vop_read_args /* { |
173 | struct vnode *a_vp; |
174 | struct uio *a_uio; |
175 | int a_ioflag; |
176 | kauth_cred_t a_cred; |
177 | } */ *ap = v; |
178 | |
179 | /* |
180 | * Return EOF for tty devices, EIO for others |
181 | */ |
182 | if ((ap->a_vp->v_vflag & VV_ISTTY) == 0) |
183 | return (EIO); |
184 | return (0); |
185 | } |
186 | |
187 | int |
188 | dead_write(void *v) |
189 | { |
190 | struct vop_write_args /* { |
191 | struct vnode *a_vp; |
192 | struct uio *a_uio; |
193 | int a_ioflag; |
194 | kauth_cred_t a_cred; |
195 | } */ *ap = v; |
196 | |
197 | (void)ap; |
198 | |
199 | return (EIO); |
200 | } |
201 | |
202 | int |
203 | dead_ioctl(void *v) |
204 | { |
205 | struct vop_ioctl_args /* { |
206 | struct vnode *a_vp; |
207 | u_long a_command; |
208 | void *a_data; |
209 | int a_fflag; |
210 | kauth_cred_t a_cred; |
211 | struct lwp *a_l; |
212 | } */ *ap = v; |
213 | |
214 | (void)ap; |
215 | |
216 | return (EBADF); |
217 | } |
218 | |
219 | int |
220 | dead_poll(void *v) |
221 | { |
222 | struct vop_poll_args /* { |
223 | struct vnode *a_vp; |
224 | int a_events; |
225 | struct lwp *a_l; |
226 | } */ *ap = v; |
227 | |
228 | /* |
229 | * Let the user find out that the descriptor is gone. |
230 | */ |
231 | return (ap->a_events); |
232 | } |
233 | |
234 | int |
235 | dead_remove(void *v) |
236 | { |
237 | struct vop_remove_args /* { |
238 | struct vnode *a_dvp; |
239 | struct vnode *a_vp; |
240 | struct componentname *a_cnp; |
241 | } */ *ap = v; |
242 | |
243 | vput(ap->a_dvp); |
244 | vput(ap->a_vp); |
245 | |
246 | return EIO; |
247 | } |
248 | |
249 | int |
250 | dead_link(void *v) |
251 | { |
252 | struct vop_link_v2_args /* { |
253 | struct vnode *a_dvp; |
254 | struct vnode *a_vp; |
255 | struct componentname *a_cnp; |
256 | } */ *ap = v; |
257 | |
258 | (void)ap; |
259 | |
260 | return EIO; |
261 | } |
262 | |
263 | int |
264 | dead_rename(void *v) |
265 | { |
266 | struct vop_rename_args /* { |
267 | struct vnode *a_fdvp; |
268 | struct vnode *a_fvp; |
269 | struct componentname *a_fcnp; |
270 | struct vnode *a_tdvp; |
271 | struct vnode *a_tvp; |
272 | struct componentname *a_tcnp; |
273 | } */ *ap = v; |
274 | |
275 | vrele(ap->a_fdvp); |
276 | vrele(ap->a_fvp); |
277 | if (ap->a_tvp != NULL && ap->a_tvp != ap->a_tdvp) |
278 | VOP_UNLOCK(ap->a_tvp); |
279 | vput(ap->a_tdvp); |
280 | if (ap->a_tvp != NULL) |
281 | vrele(ap->a_tvp); |
282 | |
283 | return EIO; |
284 | } |
285 | |
286 | int |
287 | dead_rmdir(void *v) |
288 | { |
289 | struct vop_rmdir_args /* { |
290 | struct vnode *a_dvp; |
291 | struct vnode *a_vp; |
292 | struct componentname *a_cnp; |
293 | } */ *ap = v; |
294 | |
295 | vput(ap->a_dvp); |
296 | vput(ap->a_vp); |
297 | |
298 | return EIO; |
299 | } |
300 | |
301 | int |
302 | dead_inactive(void *v) |
303 | { |
304 | struct vop_inactive_args /* { |
305 | struct vnode *a_vp; |
306 | bool *a_recycle; |
307 | } */ *ap = v; |
308 | |
309 | *ap->a_recycle = false; |
310 | VOP_UNLOCK(ap->a_vp); |
311 | |
312 | return 0; |
313 | } |
314 | |
315 | int |
316 | dead_strategy(void *v) |
317 | { |
318 | struct vop_strategy_args /* { |
319 | struct vnode *a_vp; |
320 | struct buf *a_bp; |
321 | } */ *ap = v; |
322 | struct buf *bp; |
323 | |
324 | bp = ap->a_bp; |
325 | bp->b_error = EIO; |
326 | bp->b_resid = bp->b_bcount; |
327 | biodone(ap->a_bp); |
328 | return (EIO); |
329 | } |
330 | |
331 | /* ARGSUSED */ |
332 | int |
333 | dead_print(void *v) |
334 | { |
335 | printf("tag VT_NON, dead vnode\n" ); |
336 | return 0; |
337 | } |
338 | |
339 | int |
340 | dead_getpages(void *v) |
341 | { |
342 | struct vop_getpages_args /* { |
343 | struct vnode *a_vp; |
344 | voff_t a_offset; |
345 | struct vm_page **a_m; |
346 | int *a_count; |
347 | int a_centeridx; |
348 | vm_prot_t a_access_type; |
349 | int a_advice; |
350 | int a_flags; |
351 | } */ *ap = v; |
352 | |
353 | if ((ap->a_flags & PGO_LOCKED) == 0) |
354 | mutex_exit(ap->a_vp->v_interlock); |
355 | |
356 | return (EFAULT); |
357 | } |
358 | |
359 | int |
360 | dead_putpages(void *v) |
361 | { |
362 | struct vop_putpages_args /* { |
363 | struct vnode *a_vp; |
364 | voff_t a_offlo; |
365 | voff_t a_offhi; |
366 | int a_flags; |
367 | } */ *ap = v; |
368 | |
369 | mutex_exit(ap->a_vp->v_interlock); |
370 | return (EFAULT); |
371 | } |
372 | |