|
|
1.1 ! root 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: * @(#)dead_vnops.c 7.13 (Berkeley) 4/15/91 ! 34: */ ! 35: ! 36: #include "param.h" ! 37: #include "systm.h" ! 38: #include "time.h" ! 39: #include "vnode.h" ! 40: #include "errno.h" ! 41: #include "namei.h" ! 42: #include "buf.h" ! 43: ! 44: /* ! 45: * Prototypes for dead operations on vnodes. ! 46: */ ! 47: int dead_badop(), ! 48: dead_ebadf(); ! 49: int dead_lookup __P(( ! 50: struct vnode *vp, ! 51: struct nameidata *ndp, ! 52: struct proc *p)); ! 53: #define dead_create ((int (*) __P(( \ ! 54: struct nameidata *ndp, \ ! 55: struct vattr *vap, \ ! 56: struct proc *p))) dead_badop) ! 57: #define dead_mknod ((int (*) __P(( \ ! 58: struct nameidata *ndp, \ ! 59: struct vattr *vap, \ ! 60: struct ucred *cred, \ ! 61: struct proc *p))) dead_badop) ! 62: int dead_open __P(( ! 63: struct vnode *vp, ! 64: int mode, ! 65: struct ucred *cred, ! 66: struct proc *p)); ! 67: #define dead_close ((int (*) __P(( \ ! 68: struct vnode *vp, \ ! 69: int fflag, \ ! 70: struct ucred *cred, \ ! 71: struct proc *p))) nullop) ! 72: #define dead_access ((int (*) __P(( \ ! 73: struct vnode *vp, \ ! 74: int mode, \ ! 75: struct ucred *cred, \ ! 76: struct proc *p))) dead_ebadf) ! 77: #define dead_getattr ((int (*) __P(( \ ! 78: struct vnode *vp, \ ! 79: struct vattr *vap, \ ! 80: struct ucred *cred, \ ! 81: struct proc *p))) dead_ebadf) ! 82: #define dead_setattr ((int (*) __P(( \ ! 83: struct vnode *vp, \ ! 84: struct vattr *vap, \ ! 85: struct ucred *cred, \ ! 86: struct proc *p))) dead_ebadf) ! 87: int dead_read __P(( ! 88: struct vnode *vp, ! 89: struct uio *uio, ! 90: int ioflag, ! 91: struct ucred *cred)); ! 92: int dead_write __P(( ! 93: struct vnode *vp, ! 94: struct uio *uio, ! 95: int ioflag, ! 96: struct ucred *cred)); ! 97: int dead_ioctl __P(( ! 98: struct vnode *vp, ! 99: int command, ! 100: caddr_t data, ! 101: int fflag, ! 102: struct ucred *cred, ! 103: struct proc *p)); ! 104: int dead_select __P(( ! 105: struct vnode *vp, ! 106: int which, ! 107: int fflags, ! 108: struct ucred *cred, ! 109: struct proc *p)); ! 110: #define dead_mmap ((int (*) __P(( \ ! 111: struct vnode *vp, \ ! 112: int fflags, \ ! 113: struct ucred *cred, \ ! 114: struct proc *p))) dead_badop) ! 115: #define dead_fsync ((int (*) __P(( \ ! 116: struct vnode *vp, \ ! 117: int fflags, \ ! 118: struct ucred *cred, \ ! 119: int waitfor, \ ! 120: struct proc *p))) nullop) ! 121: #define dead_seek ((int (*) __P(( \ ! 122: struct vnode *vp, \ ! 123: off_t oldoff, \ ! 124: off_t newoff, \ ! 125: struct ucred *cred))) nullop) ! 126: #define dead_remove ((int (*) __P(( \ ! 127: struct nameidata *ndp, \ ! 128: struct proc *p))) dead_badop) ! 129: #define dead_link ((int (*) __P(( \ ! 130: struct vnode *vp, \ ! 131: struct nameidata *ndp, \ ! 132: struct proc *p))) dead_badop) ! 133: #define dead_rename ((int (*) __P(( \ ! 134: struct nameidata *fndp, \ ! 135: struct nameidata *tdnp, \ ! 136: struct proc *p))) dead_badop) ! 137: #define dead_mkdir ((int (*) __P(( \ ! 138: struct nameidata *ndp, \ ! 139: struct vattr *vap, \ ! 140: struct proc *p))) dead_badop) ! 141: #define dead_rmdir ((int (*) __P(( \ ! 142: struct nameidata *ndp, \ ! 143: struct proc *p))) dead_badop) ! 144: #define dead_symlink ((int (*) __P(( \ ! 145: struct nameidata *ndp, \ ! 146: struct vattr *vap, \ ! 147: char *target, \ ! 148: struct proc *p))) dead_badop) ! 149: #define dead_readdir ((int (*) __P(( \ ! 150: struct vnode *vp, \ ! 151: struct uio *uio, \ ! 152: struct ucred *cred, \ ! 153: int *eofflagp))) dead_ebadf) ! 154: #define dead_readlink ((int (*) __P(( \ ! 155: struct vnode *vp, \ ! 156: struct uio *uio, \ ! 157: struct ucred *cred))) dead_ebadf) ! 158: #define dead_abortop ((int (*) __P(( \ ! 159: struct nameidata *ndp))) dead_badop) ! 160: #define dead_inactive ((int (*) __P(( \ ! 161: struct vnode *vp, \ ! 162: struct proc *p))) nullop) ! 163: #define dead_reclaim ((int (*) __P(( \ ! 164: struct vnode *vp))) nullop) ! 165: int dead_lock __P(( ! 166: struct vnode *vp)); ! 167: #define dead_unlock ((int (*) __P(( \ ! 168: struct vnode *vp))) nullop) ! 169: int dead_bmap __P(( ! 170: struct vnode *vp, ! 171: daddr_t bn, ! 172: struct vnode **vpp, ! 173: daddr_t *bnp)); ! 174: int dead_strategy __P(( ! 175: struct buf *bp)); ! 176: int dead_print __P(( ! 177: struct vnode *vp)); ! 178: #define dead_islocked ((int (*) __P(( \ ! 179: struct vnode *vp))) nullop) ! 180: #define dead_advlock ((int (*) __P(( \ ! 181: struct vnode *vp, \ ! 182: caddr_t id, \ ! 183: int op, \ ! 184: struct flock *fl, \ ! 185: int flags))) dead_ebadf) ! 186: ! 187: struct vnodeops dead_vnodeops = { ! 188: dead_lookup, /* lookup */ ! 189: dead_create, /* create */ ! 190: dead_mknod, /* mknod */ ! 191: dead_open, /* open */ ! 192: dead_close, /* close */ ! 193: dead_access, /* access */ ! 194: dead_getattr, /* getattr */ ! 195: dead_setattr, /* setattr */ ! 196: dead_read, /* read */ ! 197: dead_write, /* write */ ! 198: dead_ioctl, /* ioctl */ ! 199: dead_select, /* select */ ! 200: dead_mmap, /* mmap */ ! 201: dead_fsync, /* fsync */ ! 202: dead_seek, /* seek */ ! 203: dead_remove, /* remove */ ! 204: dead_link, /* link */ ! 205: dead_rename, /* rename */ ! 206: dead_mkdir, /* mkdir */ ! 207: dead_rmdir, /* rmdir */ ! 208: dead_symlink, /* symlink */ ! 209: dead_readdir, /* readdir */ ! 210: dead_readlink, /* readlink */ ! 211: dead_abortop, /* abortop */ ! 212: dead_inactive, /* inactive */ ! 213: dead_reclaim, /* reclaim */ ! 214: dead_lock, /* lock */ ! 215: dead_unlock, /* unlock */ ! 216: dead_bmap, /* bmap */ ! 217: dead_strategy, /* strategy */ ! 218: dead_print, /* print */ ! 219: dead_islocked, /* islocked */ ! 220: dead_advlock, /* advlock */ ! 221: }; ! 222: ! 223: /* ! 224: * Trivial lookup routine that always fails. ! 225: */ ! 226: /* ARGSUSED */ ! 227: dead_lookup(vp, ndp, p) ! 228: struct vnode *vp; ! 229: struct nameidata *ndp; ! 230: struct proc *p; ! 231: { ! 232: ! 233: ndp->ni_dvp = vp; ! 234: ndp->ni_vp = NULL; ! 235: return (ENOTDIR); ! 236: } ! 237: ! 238: /* ! 239: * Open always fails as if device did not exist. ! 240: */ ! 241: /* ARGSUSED */ ! 242: dead_open(vp, mode, cred, p) ! 243: struct vnode *vp; ! 244: int mode; ! 245: struct ucred *cred; ! 246: struct proc *p; ! 247: { ! 248: ! 249: return (ENXIO); ! 250: } ! 251: ! 252: /* ! 253: * Vnode op for read ! 254: */ ! 255: /* ARGSUSED */ ! 256: dead_read(vp, uio, ioflag, cred) ! 257: struct vnode *vp; ! 258: struct uio *uio; ! 259: int ioflag; ! 260: struct ucred *cred; ! 261: { ! 262: ! 263: if (chkvnlock(vp)) ! 264: panic("dead_read: lock"); ! 265: /* ! 266: * Return EOF for character devices, EIO for others ! 267: */ ! 268: if (vp->v_type != VCHR) ! 269: return (EIO); ! 270: return (0); ! 271: } ! 272: ! 273: /* ! 274: * Vnode op for write ! 275: */ ! 276: /* ARGSUSED */ ! 277: dead_write(vp, uio, ioflag, cred) ! 278: register struct vnode *vp; ! 279: struct uio *uio; ! 280: int ioflag; ! 281: struct ucred *cred; ! 282: { ! 283: ! 284: if (chkvnlock(vp)) ! 285: panic("dead_write: lock"); ! 286: return (EIO); ! 287: } ! 288: ! 289: /* ! 290: * Device ioctl operation. ! 291: */ ! 292: /* ARGSUSED */ ! 293: dead_ioctl(vp, com, data, fflag, cred, p) ! 294: struct vnode *vp; ! 295: register int com; ! 296: caddr_t data; ! 297: int fflag; ! 298: struct ucred *cred; ! 299: struct proc *p; ! 300: { ! 301: ! 302: if (!chkvnlock(vp)) ! 303: return (EBADF); ! 304: return (VOP_IOCTL(vp, com, data, fflag, cred, p)); ! 305: } ! 306: ! 307: /* ARGSUSED */ ! 308: dead_select(vp, which, fflags, cred, p) ! 309: struct vnode *vp; ! 310: int which, fflags; ! 311: struct ucred *cred; ! 312: struct proc *p; ! 313: { ! 314: ! 315: /* ! 316: * Let the user find out that the descriptor is gone. ! 317: */ ! 318: return (1); ! 319: } ! 320: ! 321: /* ! 322: * Just call the device strategy routine ! 323: */ ! 324: dead_strategy(bp) ! 325: register struct buf *bp; ! 326: { ! 327: ! 328: if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) { ! 329: bp->b_flags |= B_ERROR; ! 330: biodone(bp); ! 331: return (EIO); ! 332: } ! 333: return (VOP_STRATEGY(bp)); ! 334: } ! 335: ! 336: /* ! 337: * Wait until the vnode has finished changing state. ! 338: */ ! 339: dead_lock(vp) ! 340: struct vnode *vp; ! 341: { ! 342: ! 343: if (!chkvnlock(vp)) ! 344: return (0); ! 345: return (VOP_LOCK(vp)); ! 346: } ! 347: ! 348: /* ! 349: * Wait until the vnode has finished changing state. ! 350: */ ! 351: dead_bmap(vp, bn, vpp, bnp) ! 352: struct vnode *vp; ! 353: daddr_t bn; ! 354: struct vnode **vpp; ! 355: daddr_t *bnp; ! 356: { ! 357: ! 358: if (!chkvnlock(vp)) ! 359: return (EIO); ! 360: return (VOP_BMAP(vp, bn, vpp, bnp)); ! 361: } ! 362: ! 363: /* ! 364: * Print out the contents of a dead vnode. ! 365: */ ! 366: /* ARGSUSED */ ! 367: dead_print(vp) ! 368: struct vnode *vp; ! 369: { ! 370: ! 371: printf("tag VT_NON, dead vnode\n"); ! 372: } ! 373: ! 374: /* ! 375: * Empty vnode failed operation ! 376: */ ! 377: dead_ebadf() ! 378: { ! 379: ! 380: return (EBADF); ! 381: } ! 382: ! 383: /* ! 384: * Empty vnode bad operation ! 385: */ ! 386: dead_badop() ! 387: { ! 388: ! 389: panic("dead_badop called"); ! 390: /* NOTREACHED */ ! 391: } ! 392: ! 393: /* ! 394: * Empty vnode null operation ! 395: */ ! 396: dead_nullop() ! 397: { ! 398: ! 399: return (0); ! 400: } ! 401: ! 402: /* ! 403: * We have to wait during times when the vnode is ! 404: * in a state of change. ! 405: */ ! 406: chkvnlock(vp) ! 407: register struct vnode *vp; ! 408: { ! 409: int locked = 0; ! 410: ! 411: while (vp->v_flag & VXLOCK) { ! 412: vp->v_flag |= VXWANT; ! 413: sleep((caddr_t)vp, PINOD); ! 414: locked = 1; ! 415: } ! 416: return (locked); ! 417: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.