Annotation of sys/miscfs/deadfs/dead_vnops.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: dead_vnops.c,v 1.18 2007/06/01 23:47:57 deraadt Exp $ */
! 2: /* $NetBSD: dead_vnops.c,v 1.16 1996/02/13 13:12:48 mycroft Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1989, 1993
! 6: * The Regents of the University of California. All rights reserved.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: * 3. Neither the name of the University nor the names of its contributors
! 17: * may be used to endorse or promote products derived from this software
! 18: * without specific prior written permission.
! 19: *
! 20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 30: * SUCH DAMAGE.
! 31: *
! 32: * @(#)dead_vnops.c 8.2 (Berkeley) 11/21/94
! 33: */
! 34:
! 35: #include <sys/param.h>
! 36: #include <sys/systm.h>
! 37: #include <sys/time.h>
! 38: #include <sys/vnode.h>
! 39: #include <sys/errno.h>
! 40: #include <sys/namei.h>
! 41: #include <sys/buf.h>
! 42: #include <sys/proc.h>
! 43: #include <sys/poll.h>
! 44:
! 45: /*
! 46: * Prototypes for dead operations on vnodes.
! 47: */
! 48: int dead_badop(void *);
! 49: int dead_ebadf(void *);
! 50:
! 51: int dead_lookup(void *);
! 52: #define dead_create dead_badop
! 53: #define dead_mknod dead_badop
! 54: int dead_open(void *);
! 55: #define dead_close nullop
! 56: #define dead_access dead_ebadf
! 57: #define dead_getattr dead_ebadf
! 58: #define dead_setattr dead_ebadf
! 59: int dead_read(void *);
! 60: int dead_write(void *);
! 61: int dead_ioctl(void *);
! 62: int dead_poll(void *);
! 63: #define dead_fsync nullop
! 64: #define dead_remove dead_badop
! 65: #define dead_link dead_badop
! 66: #define dead_rename dead_badop
! 67: #define dead_mkdir dead_badop
! 68: #define dead_rmdir dead_badop
! 69: #define dead_symlink dead_badop
! 70: #define dead_readdir dead_ebadf
! 71: #define dead_readlink dead_ebadf
! 72: #define dead_abortop dead_badop
! 73: #define dead_inactive nullop
! 74: #define dead_reclaim nullop
! 75: int dead_lock(void *);
! 76: #define dead_unlock vop_generic_unlock
! 77: int dead_bmap(void *);
! 78: int dead_strategy(void *);
! 79: int dead_print(void *);
! 80: #define dead_islocked vop_generic_islocked
! 81: #define dead_pathconf dead_ebadf
! 82: #define dead_advlock dead_ebadf
! 83: #define dead_bwrite nullop
! 84:
! 85: int chkvnlock(struct vnode *);
! 86:
! 87: int (**dead_vnodeop_p)(void *);
! 88:
! 89: struct vnodeopv_entry_desc dead_vnodeop_entries[] = {
! 90: { &vop_default_desc, vn_default_error },
! 91: { &vop_lookup_desc, dead_lookup }, /* lookup */
! 92: { &vop_create_desc, dead_create }, /* create */
! 93: { &vop_mknod_desc, dead_mknod }, /* mknod */
! 94: { &vop_open_desc, dead_open }, /* open */
! 95: { &vop_close_desc, dead_close }, /* close */
! 96: { &vop_access_desc, dead_access }, /* access */
! 97: { &vop_getattr_desc, dead_getattr }, /* getattr */
! 98: { &vop_setattr_desc, dead_setattr }, /* setattr */
! 99: { &vop_read_desc, dead_read }, /* read */
! 100: { &vop_write_desc, dead_write }, /* write */
! 101: { &vop_ioctl_desc, dead_ioctl }, /* ioctl */
! 102: { &vop_poll_desc, dead_poll }, /* poll */
! 103: { &vop_fsync_desc, dead_fsync }, /* fsync */
! 104: { &vop_remove_desc, dead_remove }, /* remove */
! 105: { &vop_link_desc, dead_link }, /* link */
! 106: { &vop_rename_desc, dead_rename }, /* rename */
! 107: { &vop_mkdir_desc, dead_mkdir }, /* mkdir */
! 108: { &vop_rmdir_desc, dead_rmdir }, /* rmdir */
! 109: { &vop_symlink_desc, dead_symlink }, /* symlink */
! 110: { &vop_readdir_desc, dead_readdir }, /* readdir */
! 111: { &vop_readlink_desc, dead_readlink }, /* readlink */
! 112: { &vop_abortop_desc, dead_abortop }, /* abortop */
! 113: { &vop_inactive_desc, dead_inactive }, /* inactive */
! 114: { &vop_reclaim_desc, dead_reclaim }, /* reclaim */
! 115: { &vop_lock_desc, dead_lock }, /* lock */
! 116: { &vop_unlock_desc, dead_unlock }, /* unlock */
! 117: { &vop_bmap_desc, dead_bmap }, /* bmap */
! 118: { &vop_strategy_desc, dead_strategy }, /* strategy */
! 119: { &vop_print_desc, dead_print }, /* print */
! 120: { &vop_islocked_desc, dead_islocked }, /* islocked */
! 121: { &vop_pathconf_desc, dead_pathconf }, /* pathconf */
! 122: { &vop_advlock_desc, dead_advlock }, /* advlock */
! 123: { &vop_bwrite_desc, dead_bwrite }, /* bwrite */
! 124: { (struct vnodeop_desc*)NULL, (int(*)(void *))NULL }
! 125: };
! 126: struct vnodeopv_desc dead_vnodeop_opv_desc =
! 127: { &dead_vnodeop_p, dead_vnodeop_entries };
! 128:
! 129: /*
! 130: * Trivial lookup routine that always fails.
! 131: */
! 132: /* ARGSUSED */
! 133: int
! 134: dead_lookup(void *v)
! 135: {
! 136: struct vop_lookup_args *ap = v;
! 137:
! 138: *ap->a_vpp = NULL;
! 139: return (ENOTDIR);
! 140: }
! 141:
! 142: /*
! 143: * Open always fails as if device did not exist.
! 144: */
! 145: /* ARGSUSED */
! 146: int
! 147: dead_open(void *v)
! 148: {
! 149: return (ENXIO);
! 150: }
! 151:
! 152: /*
! 153: * Vnode op for read
! 154: */
! 155: /* ARGSUSED */
! 156: int
! 157: dead_read(void *v)
! 158: {
! 159: struct vop_read_args *ap = v;
! 160:
! 161: if (chkvnlock(ap->a_vp))
! 162: panic("dead_read: lock");
! 163: /*
! 164: * Return EOF for tty devices, EIO for others
! 165: */
! 166: if ((ap->a_vp->v_flag & VISTTY) == 0)
! 167: return (EIO);
! 168: return (0);
! 169: }
! 170:
! 171: /*
! 172: * Vnode op for write
! 173: */
! 174: /* ARGSUSED */
! 175: int
! 176: dead_write(void *v)
! 177: {
! 178: struct vop_write_args *ap = v;
! 179:
! 180: if (chkvnlock(ap->a_vp))
! 181: panic("dead_write: lock");
! 182: return (EIO);
! 183: }
! 184:
! 185: /*
! 186: * Device ioctl operation.
! 187: */
! 188: /* ARGSUSED */
! 189: int
! 190: dead_ioctl(void *v)
! 191: {
! 192: struct vop_ioctl_args *ap = v;
! 193:
! 194: if (!chkvnlock(ap->a_vp))
! 195: return (EBADF);
! 196: return (VCALL(ap->a_vp, VOFFSET(vop_ioctl), ap));
! 197: }
! 198:
! 199: /* ARGSUSED */
! 200: int
! 201: dead_poll(void *v)
! 202: {
! 203: #if 0
! 204: struct vop_poll_args *ap = v;
! 205: #endif
! 206:
! 207: /*
! 208: * Let the user find out that the descriptor is gone.
! 209: */
! 210: return (POLLHUP);
! 211: }
! 212:
! 213: /*
! 214: * Just call the device strategy routine
! 215: */
! 216: int
! 217: dead_strategy(void *v)
! 218: {
! 219: struct vop_strategy_args *ap = v;
! 220: int s;
! 221:
! 222: if (ap->a_bp->b_vp == NULL || !chkvnlock(ap->a_bp->b_vp)) {
! 223: ap->a_bp->b_flags |= B_ERROR;
! 224: s = splbio();
! 225: biodone(ap->a_bp);
! 226: splx(s);
! 227: return (EIO);
! 228: }
! 229: return (VOP_STRATEGY(ap->a_bp));
! 230: }
! 231:
! 232: /*
! 233: * Wait until the vnode has finished changing state.
! 234: */
! 235: int
! 236: dead_lock(void *v)
! 237: {
! 238: struct vop_lock_args *ap = v;
! 239: struct vnode *vp = ap->a_vp;
! 240:
! 241: if (ap->a_flags & LK_DRAIN || !chkvnlock(vp))
! 242: return (0);
! 243:
! 244: return (VCALL(vp, VOFFSET(vop_lock), ap));
! 245: }
! 246:
! 247: /*
! 248: * Wait until the vnode has finished changing state.
! 249: */
! 250: int
! 251: dead_bmap(void *v)
! 252: {
! 253: struct vop_bmap_args *ap = v;
! 254:
! 255: if (!chkvnlock(ap->a_vp))
! 256: return (EIO);
! 257: return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp));
! 258: }
! 259:
! 260: /*
! 261: * Print out the contents of a dead vnode.
! 262: */
! 263: /* ARGSUSED */
! 264: int
! 265: dead_print(void *v)
! 266: {
! 267: printf("tag VT_NON, dead vnode\n");
! 268: return 0;
! 269: }
! 270:
! 271: /*
! 272: * Empty vnode failed operation
! 273: */
! 274: /*ARGSUSED*/
! 275: int
! 276: dead_ebadf(void *v)
! 277: {
! 278: return (EBADF);
! 279: }
! 280:
! 281: /*
! 282: * Empty vnode bad operation
! 283: */
! 284: /*ARGSUSED*/
! 285: int
! 286: dead_badop(void *v)
! 287: {
! 288: panic("dead_badop called");
! 289: /* NOTREACHED */
! 290: }
! 291:
! 292: /*
! 293: * We have to wait during times when the vnode is
! 294: * in a state of change.
! 295: */
! 296: int
! 297: chkvnlock(struct vnode *vp)
! 298: {
! 299: int locked = 0;
! 300:
! 301: while (vp->v_flag & VXLOCK) {
! 302: vp->v_flag |= VXWANT;
! 303: tsleep(vp, PINOD, "chkvnlock", 0);
! 304: locked = 1;
! 305: }
! 306: return (locked);
! 307: }
CVSweb