1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * from: @(#)dead_vnops.c 7.13 (Berkeley) 4/15/91 34 * $Id: dead_vnops.c,v 1.5 1993/09/07 15:41:08 ws Exp $ 35 */ 36 37 #include "param.h" 38 #include "systm.h" 39 #include "time.h" 40 #include "vnode.h" 41 #include "errno.h" 42 #include "namei.h" 43 #include "buf.h" 44 45 /* 46 * Prototypes for dead operations on vnodes. 47 */ 48 volatile void dead_badop(); 49 int dead_ebadf(); 50 int dead_lookup __P(( 51 struct vnode *vp, 52 struct nameidata *ndp, 53 struct proc *p)); 54 #define dead_create ((int (*) __P(( \ 55 struct nameidata *ndp, \ 56 struct vattr *vap, \ 57 struct proc *p))) dead_badop) 58 #define dead_mknod ((int (*) __P(( \ 59 struct nameidata *ndp, \ 60 struct vattr *vap, \ 61 struct ucred *cred, \ 62 struct proc *p))) dead_badop) 63 int dead_open __P(( 64 struct vnode *vp, 65 int mode, 66 struct ucred *cred, 67 struct proc *p)); 68 #define dead_close ((int (*) __P(( \ 69 struct vnode *vp, \ 70 int fflag, \ 71 struct ucred *cred, \ 72 struct proc *p))) nullop) 73 #define dead_access ((int (*) __P(( \ 74 struct vnode *vp, \ 75 int mode, \ 76 struct ucred *cred, \ 77 struct proc *p))) dead_ebadf) 78 #define dead_getattr ((int (*) __P(( \ 79 struct vnode *vp, \ 80 struct vattr *vap, \ 81 struct ucred *cred, \ 82 struct proc *p))) dead_ebadf) 83 #define dead_setattr ((int (*) __P(( \ 84 struct vnode *vp, \ 85 struct vattr *vap, \ 86 struct ucred *cred, \ 87 struct proc *p))) dead_ebadf) 88 int dead_read __P(( 89 struct vnode *vp, 90 struct uio *uio, 91 int ioflag, 92 struct ucred *cred)); 93 int dead_write __P(( 94 struct vnode *vp, 95 struct uio *uio, 96 int ioflag, 97 struct ucred *cred)); 98 int dead_ioctl __P(( 99 struct vnode *vp, 100 int command, 101 caddr_t data, 102 int fflag, 103 struct ucred *cred, 104 struct proc *p)); 105 int dead_select __P(( 106 struct vnode *vp, 107 int which, 108 int fflags, 109 struct ucred *cred, 110 struct proc *p)); 111 #define dead_mmap ((int (*) __P(( \ 112 struct vnode *vp, \ 113 int fflags, \ 114 struct ucred *cred, \ 115 struct proc *p))) dead_badop) 116 #define dead_fsync ((int (*) __P(( \ 117 struct vnode *vp, \ 118 int fflags, \ 119 struct ucred *cred, \ 120 int waitfor, \ 121 struct proc *p))) nullop) 122 #define dead_seek ((int (*) __P(( \ 123 struct vnode *vp, \ 124 off_t oldoff, \ 125 off_t newoff, \ 126 struct ucred *cred))) nullop) 127 #define dead_remove ((int (*) __P(( \ 128 struct nameidata *ndp, \ 129 struct proc *p))) dead_badop) 130 #define dead_link ((int (*) __P(( \ 131 struct vnode *vp, \ 132 struct nameidata *ndp, \ 133 struct proc *p))) dead_badop) 134 #define dead_rename ((int (*) __P(( \ 135 struct nameidata *fndp, \ 136 struct nameidata *tdnp, \ 137 struct proc *p))) dead_badop) 138 #define dead_mkdir ((int (*) __P(( \ 139 struct nameidata *ndp, \ 140 struct vattr *vap, \ 141 struct proc *p))) dead_badop) 142 #define dead_rmdir ((int (*) __P(( \ 143 struct nameidata *ndp, \ 144 struct proc *p))) dead_badop) 145 #define dead_symlink ((int (*) __P(( \ 146 struct nameidata *ndp, \ 147 struct vattr *vap, \ 148 char *target, \ 149 struct proc *p))) dead_badop) 150 #define dead_readdir ((int (*) __P(( \ 151 struct vnode *vp, \ 152 struct uio *uio, \ 153 struct ucred *cred, \ 154 int *eofflagp, \ 155 u_int *cookies, \ 156 int ncookies))) dead_ebadf) 157 #define dead_readlink ((int (*) __P(( \ 158 struct vnode *vp, \ 159 struct uio *uio, \ 160 struct ucred *cred))) dead_ebadf) 161 #define dead_abortop ((int (*) __P(( \ 162 struct nameidata *ndp))) dead_badop) 163 #define dead_inactive ((int (*) __P(( \ 164 struct vnode *vp, \ 165 struct proc *p))) nullop) 166 #define dead_reclaim ((int (*) __P(( \ 167 struct vnode *vp))) nullop) 168 int dead_lock __P(( 169 struct vnode *vp)); 170 #define dead_unlock ((int (*) __P(( \ 171 struct vnode *vp))) nullop) 172 int dead_bmap __P(( 173 struct vnode *vp, 174 daddr_t bn, 175 struct vnode **vpp, 176 daddr_t *bnp)); 177 int dead_strategy __P(( 178 struct buf *bp)); 179 void dead_print __P(( 180 struct vnode *vp)); 181 #define dead_islocked ((int (*) __P(( \ 182 struct vnode *vp))) nullop) 183 #define dead_advlock ((int (*) __P(( \ 184 struct vnode *vp, \ 185 caddr_t id, \ 186 int op, \ 187 struct flock *fl, \ 188 int flags))) dead_ebadf) 189 int chkvnlock __P(( 190 struct vnode *vp)); 191 192 struct vnodeops dead_vnodeops = { 193 dead_lookup, /* lookup */ 194 dead_create, /* create */ 195 dead_mknod, /* mknod */ 196 dead_open, /* open */ 197 dead_close, /* close */ 198 dead_access, /* access */ 199 dead_getattr, /* getattr */ 200 dead_setattr, /* setattr */ 201 dead_read, /* read */ 202 dead_write, /* write */ 203 dead_ioctl, /* ioctl */ 204 dead_select, /* select */ 205 dead_mmap, /* mmap */ 206 dead_fsync, /* fsync */ 207 dead_seek, /* seek */ 208 dead_remove, /* remove */ 209 dead_link, /* link */ 210 dead_rename, /* rename */ 211 dead_mkdir, /* mkdir */ 212 dead_rmdir, /* rmdir */ 213 dead_symlink, /* symlink */ 214 dead_readdir, /* readdir */ 215 dead_readlink, /* readlink */ 216 dead_abortop, /* abortop */ 217 dead_inactive, /* inactive */ 218 dead_reclaim, /* reclaim */ 219 dead_lock, /* lock */ 220 dead_unlock, /* unlock */ 221 dead_bmap, /* bmap */ 222 dead_strategy, /* strategy */ 223 dead_print, /* print */ 224 dead_islocked, /* islocked */ 225 dead_advlock, /* advlock */ 226 }; 227 228 /* 229 * Trivial lookup routine that always fails. 230 */ 231 /* ARGSUSED */ 232 int 233 dead_lookup(vp, ndp, p) 234 struct vnode *vp; 235 struct nameidata *ndp; 236 struct proc *p; 237 { 238 239 ndp->ni_dvp = vp; 240 ndp->ni_vp = NULL; 241 return (ENOTDIR); 242 } 243 244 /* 245 * Open always fails as if device did not exist. 246 */ 247 /* ARGSUSED */ 248 int 249 dead_open(vp, mode, cred, p) 250 struct vnode *vp; 251 int mode; 252 struct ucred *cred; 253 struct proc *p; 254 { 255 256 return (ENXIO); 257 } 258 259 /* 260 * Vnode op for read 261 */ 262 /* ARGSUSED */ 263 int 264 dead_read(vp, uio, ioflag, cred) 265 struct vnode *vp; 266 struct uio *uio; 267 int ioflag; 268 struct ucred *cred; 269 { 270 271 if (chkvnlock(vp)) 272 panic("dead_read: lock"); 273 /* 274 * Return EOF for character devices, EIO for others 275 */ 276 if (vp->v_type != VCHR) 277 return (EIO); 278 return (0); 279 } 280 281 /* 282 * Vnode op for write 283 */ 284 /* ARGSUSED */ 285 int 286 dead_write(vp, uio, ioflag, cred) 287 register struct vnode *vp; 288 struct uio *uio; 289 int ioflag; 290 struct ucred *cred; 291 { 292 293 if (chkvnlock(vp)) 294 panic("dead_write: lock"); 295 return (EIO); 296 } 297 298 /* 299 * Device ioctl operation. 300 */ 301 /* ARGSUSED */ 302 int 303 dead_ioctl(vp, com, data, fflag, cred, p) 304 struct vnode *vp; 305 register int com; 306 caddr_t data; 307 int fflag; 308 struct ucred *cred; 309 struct proc *p; 310 { 311 312 if (!chkvnlock(vp)) 313 return (EBADF); 314 return (VOP_IOCTL(vp, com, data, fflag, cred, p)); 315 } 316 317 /* ARGSUSED */ 318 int 319 dead_select(vp, which, fflags, cred, p) 320 struct vnode *vp; 321 int which, fflags; 322 struct ucred *cred; 323 struct proc *p; 324 { 325 326 /* 327 * Let the user find out that the descriptor is gone. 328 */ 329 return (1); 330 } 331 332 /* 333 * Just call the device strategy routine 334 */ 335 int 336 dead_strategy(bp) 337 register struct buf *bp; 338 { 339 340 if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) { 341 bp->b_flags |= B_ERROR; 342 biodone(bp); 343 return (EIO); 344 } 345 return (VOP_STRATEGY(bp)); 346 } 347 348 /* 349 * Wait until the vnode has finished changing state. 350 */ 351 int 352 dead_lock(vp) 353 struct vnode *vp; 354 { 355 356 if (!chkvnlock(vp)) 357 return (0); 358 return (VOP_LOCK(vp)); 359 } 360 361 /* 362 * Wait until the vnode has finished changing state. 363 */ 364 int 365 dead_bmap(vp, bn, vpp, bnp) 366 struct vnode *vp; 367 daddr_t bn; 368 struct vnode **vpp; 369 daddr_t *bnp; 370 { 371 372 if (!chkvnlock(vp)) 373 return (EIO); 374 return (VOP_BMAP(vp, bn, vpp, bnp)); 375 } 376 377 /* 378 * Print out the contents of a dead vnode. 379 */ 380 /* ARGSUSED */ 381 void 382 dead_print(vp) 383 struct vnode *vp; 384 { 385 386 printf("tag VT_NON, dead vnode\n"); 387 } 388 389 /* 390 * Empty vnode failed operation 391 */ 392 int 393 dead_ebadf() 394 { 395 396 return (EBADF); 397 } 398 399 /* 400 * Empty vnode bad operation 401 */ 402 volatile void 403 dead_badop() 404 { 405 406 panic("dead_badop called"); 407 /* NOTREACHED */ 408 } 409 410 /* 411 * Empty vnode null operation 412 */ 413 int 414 dead_nullop() 415 { 416 417 return (0); 418 } 419 420 /* 421 * We have to wait during times when the vnode is 422 * in a state of change. 423 */ 424 int 425 chkvnlock(vp) 426 register struct vnode *vp; 427 { 428 int locked = 0; 429 430 while (vp->v_flag & VXLOCK) { 431 vp->v_flag |= VXWANT; 432 tsleep((caddr_t)vp, PINOD, "chkvunlock", 0); 433 locked = 1; 434 } 435 return (locked); 436 } 437