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