[BACK]Return to dead_vnops.c CVS log [TXT][DIR] Up to [local] / sys / miscfs / deadfs

Annotation of sys/miscfs/deadfs/dead_vnops.c, Revision 1.1.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