xref: /netbsd-src/sys/miscfs/deadfs/dead_vnops.c (revision 26784725eeed8e5fc5898ec384aab2af43e2e264)
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