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