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