1 /* $NetBSD: dead_vnops.c,v 1.59 2015/04/20 23:30:58 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.59 2015/04/20 23:30:58 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/genfs/genfs.h> 47 48 /* 49 * Prototypes for dead operations on vnodes. 50 */ 51 #define dead_bwrite genfs_nullop 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_args /* { 238 struct vnode *a_dvp; 239 struct vnode *a_vp; 240 struct componentname *a_cnp; 241 } */ *ap = v; 242 243 vput(ap->a_dvp); 244 vput(ap->a_vp); 245 246 return EIO; 247 } 248 249 int 250 dead_link(void *v) 251 { 252 struct vop_link_v2_args /* { 253 struct vnode *a_dvp; 254 struct vnode *a_vp; 255 struct componentname *a_cnp; 256 } */ *ap = v; 257 258 (void)ap; 259 260 return EIO; 261 } 262 263 int 264 dead_rename(void *v) 265 { 266 struct vop_rename_args /* { 267 struct vnode *a_fdvp; 268 struct vnode *a_fvp; 269 struct componentname *a_fcnp; 270 struct vnode *a_tdvp; 271 struct vnode *a_tvp; 272 struct componentname *a_tcnp; 273 } */ *ap = v; 274 275 vrele(ap->a_fdvp); 276 vrele(ap->a_fvp); 277 if (ap->a_tvp != NULL && ap->a_tvp != ap->a_tdvp) 278 VOP_UNLOCK(ap->a_tvp); 279 vput(ap->a_tdvp); 280 if (ap->a_tvp != NULL) 281 vrele(ap->a_tvp); 282 283 return EIO; 284 } 285 286 int 287 dead_rmdir(void *v) 288 { 289 struct vop_rmdir_args /* { 290 struct vnode *a_dvp; 291 struct vnode *a_vp; 292 struct componentname *a_cnp; 293 } */ *ap = v; 294 295 vput(ap->a_dvp); 296 vput(ap->a_vp); 297 298 return EIO; 299 } 300 301 int 302 dead_inactive(void *v) 303 { 304 struct vop_inactive_args /* { 305 struct vnode *a_vp; 306 bool *a_recycle; 307 } */ *ap = v; 308 309 *ap->a_recycle = false; 310 VOP_UNLOCK(ap->a_vp); 311 312 return 0; 313 } 314 315 int 316 dead_strategy(void *v) 317 { 318 struct vop_strategy_args /* { 319 struct vnode *a_vp; 320 struct buf *a_bp; 321 } */ *ap = v; 322 struct buf *bp; 323 324 bp = ap->a_bp; 325 bp->b_error = EIO; 326 bp->b_resid = bp->b_bcount; 327 biodone(ap->a_bp); 328 return (EIO); 329 } 330 331 /* ARGSUSED */ 332 int 333 dead_print(void *v) 334 { 335 printf("tag VT_NON, dead vnode\n"); 336 return 0; 337 } 338 339 int 340 dead_getpages(void *v) 341 { 342 struct vop_getpages_args /* { 343 struct vnode *a_vp; 344 voff_t a_offset; 345 struct vm_page **a_m; 346 int *a_count; 347 int a_centeridx; 348 vm_prot_t a_access_type; 349 int a_advice; 350 int a_flags; 351 } */ *ap = v; 352 353 if ((ap->a_flags & PGO_LOCKED) == 0) 354 mutex_exit(ap->a_vp->v_interlock); 355 356 return (EFAULT); 357 } 358 359 int 360 dead_putpages(void *v) 361 { 362 struct vop_putpages_args /* { 363 struct vnode *a_vp; 364 voff_t a_offlo; 365 voff_t a_offhi; 366 int a_flags; 367 } */ *ap = v; 368 369 mutex_exit(ap->a_vp->v_interlock); 370 return (EFAULT); 371 } 372