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