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