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