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