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.3 1993/06/27 06:01:27 andrew 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))) dead_ebadf) 155 #define dead_readlink ((int (*) __P(( \ 156 struct vnode *vp, \ 157 struct uio *uio, \ 158 struct ucred *cred))) dead_ebadf) 159 #define dead_abortop ((int (*) __P(( \ 160 struct nameidata *ndp))) dead_badop) 161 #define dead_inactive ((int (*) __P(( \ 162 struct vnode *vp, \ 163 struct proc *p))) nullop) 164 #define dead_reclaim ((int (*) __P(( \ 165 struct vnode *vp))) nullop) 166 int dead_lock __P(( 167 struct vnode *vp)); 168 #define dead_unlock ((int (*) __P(( \ 169 struct vnode *vp))) nullop) 170 int dead_bmap __P(( 171 struct vnode *vp, 172 daddr_t bn, 173 struct vnode **vpp, 174 daddr_t *bnp)); 175 int dead_strategy __P(( 176 struct buf *bp)); 177 void dead_print __P(( 178 struct vnode *vp)); 179 #define dead_islocked ((int (*) __P(( \ 180 struct vnode *vp))) nullop) 181 #define dead_advlock ((int (*) __P(( \ 182 struct vnode *vp, \ 183 caddr_t id, \ 184 int op, \ 185 struct flock *fl, \ 186 int flags))) dead_ebadf) 187 int chkvnlock __P(( 188 struct vnode *vp)); 189 190 struct vnodeops dead_vnodeops = { 191 dead_lookup, /* lookup */ 192 dead_create, /* create */ 193 dead_mknod, /* mknod */ 194 dead_open, /* open */ 195 dead_close, /* close */ 196 dead_access, /* access */ 197 dead_getattr, /* getattr */ 198 dead_setattr, /* setattr */ 199 dead_read, /* read */ 200 dead_write, /* write */ 201 dead_ioctl, /* ioctl */ 202 dead_select, /* select */ 203 dead_mmap, /* mmap */ 204 dead_fsync, /* fsync */ 205 dead_seek, /* seek */ 206 dead_remove, /* remove */ 207 dead_link, /* link */ 208 dead_rename, /* rename */ 209 dead_mkdir, /* mkdir */ 210 dead_rmdir, /* rmdir */ 211 dead_symlink, /* symlink */ 212 dead_readdir, /* readdir */ 213 dead_readlink, /* readlink */ 214 dead_abortop, /* abortop */ 215 dead_inactive, /* inactive */ 216 dead_reclaim, /* reclaim */ 217 dead_lock, /* lock */ 218 dead_unlock, /* unlock */ 219 dead_bmap, /* bmap */ 220 dead_strategy, /* strategy */ 221 dead_print, /* print */ 222 dead_islocked, /* islocked */ 223 dead_advlock, /* advlock */ 224 }; 225 226 /* 227 * Trivial lookup routine that always fails. 228 */ 229 /* ARGSUSED */ 230 int 231 dead_lookup(vp, ndp, p) 232 struct vnode *vp; 233 struct nameidata *ndp; 234 struct proc *p; 235 { 236 237 ndp->ni_dvp = vp; 238 ndp->ni_vp = NULL; 239 return (ENOTDIR); 240 } 241 242 /* 243 * Open always fails as if device did not exist. 244 */ 245 /* ARGSUSED */ 246 int 247 dead_open(vp, mode, cred, p) 248 struct vnode *vp; 249 int mode; 250 struct ucred *cred; 251 struct proc *p; 252 { 253 254 return (ENXIO); 255 } 256 257 /* 258 * Vnode op for read 259 */ 260 /* ARGSUSED */ 261 int 262 dead_read(vp, uio, ioflag, cred) 263 struct vnode *vp; 264 struct uio *uio; 265 int ioflag; 266 struct ucred *cred; 267 { 268 269 if (chkvnlock(vp)) 270 panic("dead_read: lock"); 271 /* 272 * Return EOF for character devices, EIO for others 273 */ 274 if (vp->v_type != VCHR) 275 return (EIO); 276 return (0); 277 } 278 279 /* 280 * Vnode op for write 281 */ 282 /* ARGSUSED */ 283 int 284 dead_write(vp, uio, ioflag, cred) 285 register struct vnode *vp; 286 struct uio *uio; 287 int ioflag; 288 struct ucred *cred; 289 { 290 291 if (chkvnlock(vp)) 292 panic("dead_write: lock"); 293 return (EIO); 294 } 295 296 /* 297 * Device ioctl operation. 298 */ 299 /* ARGSUSED */ 300 int 301 dead_ioctl(vp, com, data, fflag, cred, p) 302 struct vnode *vp; 303 register int com; 304 caddr_t data; 305 int fflag; 306 struct ucred *cred; 307 struct proc *p; 308 { 309 310 if (!chkvnlock(vp)) 311 return (EBADF); 312 return (VOP_IOCTL(vp, com, data, fflag, cred, p)); 313 } 314 315 /* ARGSUSED */ 316 int 317 dead_select(vp, which, fflags, cred, p) 318 struct vnode *vp; 319 int which, fflags; 320 struct ucred *cred; 321 struct proc *p; 322 { 323 324 /* 325 * Let the user find out that the descriptor is gone. 326 */ 327 return (1); 328 } 329 330 /* 331 * Just call the device strategy routine 332 */ 333 int 334 dead_strategy(bp) 335 register struct buf *bp; 336 { 337 338 if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) { 339 bp->b_flags |= B_ERROR; 340 biodone(bp); 341 return (EIO); 342 } 343 return (VOP_STRATEGY(bp)); 344 } 345 346 /* 347 * Wait until the vnode has finished changing state. 348 */ 349 int 350 dead_lock(vp) 351 struct vnode *vp; 352 { 353 354 if (!chkvnlock(vp)) 355 return (0); 356 return (VOP_LOCK(vp)); 357 } 358 359 /* 360 * Wait until the vnode has finished changing state. 361 */ 362 int 363 dead_bmap(vp, bn, vpp, bnp) 364 struct vnode *vp; 365 daddr_t bn; 366 struct vnode **vpp; 367 daddr_t *bnp; 368 { 369 370 if (!chkvnlock(vp)) 371 return (EIO); 372 return (VOP_BMAP(vp, bn, vpp, bnp)); 373 } 374 375 /* 376 * Print out the contents of a dead vnode. 377 */ 378 /* ARGSUSED */ 379 void 380 dead_print(vp) 381 struct vnode *vp; 382 { 383 384 printf("tag VT_NON, dead vnode\n"); 385 } 386 387 /* 388 * Empty vnode failed operation 389 */ 390 int 391 dead_ebadf() 392 { 393 394 return (EBADF); 395 } 396 397 /* 398 * Empty vnode bad operation 399 */ 400 volatile void 401 dead_badop() 402 { 403 404 panic("dead_badop called"); 405 /* NOTREACHED */ 406 } 407 408 /* 409 * Empty vnode null operation 410 */ 411 int 412 dead_nullop() 413 { 414 415 return (0); 416 } 417 418 /* 419 * We have to wait during times when the vnode is 420 * in a state of change. 421 */ 422 int 423 chkvnlock(vp) 424 register struct vnode *vp; 425 { 426 int locked = 0; 427 428 while (vp->v_flag & VXLOCK) { 429 vp->v_flag |= VXWANT; 430 sleep((caddr_t)vp, PINOD); 431 locked = 1; 432 } 433 return (locked); 434 } 435