Home | History | Annotate | Line # | Download | only in deadfs
dead_vnops.c revision 1.8
      1  1.1      cgd /*
      2  1.8  mycroft  * Copyright (c) 1989, 1993
      3  1.8  mycroft  *	The Regents of the University of California.  All rights reserved.
      4  1.1      cgd  *
      5  1.1      cgd  * Redistribution and use in source and binary forms, with or without
      6  1.1      cgd  * modification, are permitted provided that the following conditions
      7  1.1      cgd  * are met:
      8  1.1      cgd  * 1. Redistributions of source code must retain the above copyright
      9  1.1      cgd  *    notice, this list of conditions and the following disclaimer.
     10  1.1      cgd  * 2. Redistributions in binary form must reproduce the above copyright
     11  1.1      cgd  *    notice, this list of conditions and the following disclaimer in the
     12  1.1      cgd  *    documentation and/or other materials provided with the distribution.
     13  1.1      cgd  * 3. All advertising materials mentioning features or use of this software
     14  1.1      cgd  *    must display the following acknowledgement:
     15  1.1      cgd  *	This product includes software developed by the University of
     16  1.1      cgd  *	California, Berkeley and its contributors.
     17  1.1      cgd  * 4. Neither the name of the University nor the names of its contributors
     18  1.1      cgd  *    may be used to endorse or promote products derived from this software
     19  1.1      cgd  *    without specific prior written permission.
     20  1.1      cgd  *
     21  1.1      cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  1.1      cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  1.1      cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  1.1      cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  1.1      cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  1.1      cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  1.1      cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  1.1      cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  1.1      cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  1.1      cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  1.1      cgd  * SUCH DAMAGE.
     32  1.1      cgd  *
     33  1.8  mycroft  *	from: @(#)dead_vnops.c	8.1 (Berkeley) 6/10/93
     34  1.8  mycroft  *	$Id: dead_vnops.c,v 1.8 1994/06/08 11:33:09 mycroft Exp $
     35  1.1      cgd  */
     36  1.1      cgd 
     37  1.6  mycroft #include <sys/param.h>
     38  1.6  mycroft #include <sys/systm.h>
     39  1.6  mycroft #include <sys/time.h>
     40  1.6  mycroft #include <sys/vnode.h>
     41  1.6  mycroft #include <sys/errno.h>
     42  1.6  mycroft #include <sys/namei.h>
     43  1.6  mycroft #include <sys/buf.h>
     44  1.1      cgd 
     45  1.1      cgd /*
     46  1.1      cgd  * Prototypes for dead operations on vnodes.
     47  1.1      cgd  */
     48  1.8  mycroft int	dead_badop(),
     49  1.8  mycroft 	dead_ebadf();
     50  1.8  mycroft int	dead_lookup __P((struct vop_lookup_args *));
     51  1.8  mycroft #define dead_create ((int (*) __P((struct  vop_create_args *)))dead_badop)
     52  1.8  mycroft #define dead_mknod ((int (*) __P((struct  vop_mknod_args *)))dead_badop)
     53  1.8  mycroft int	dead_open __P((struct vop_open_args *));
     54  1.8  mycroft #define dead_close ((int (*) __P((struct  vop_close_args *)))nullop)
     55  1.8  mycroft #define dead_access ((int (*) __P((struct  vop_access_args *)))dead_ebadf)
     56  1.8  mycroft #define dead_getattr ((int (*) __P((struct  vop_getattr_args *)))dead_ebadf)
     57  1.8  mycroft #define dead_setattr ((int (*) __P((struct  vop_setattr_args *)))dead_ebadf)
     58  1.8  mycroft int	dead_read __P((struct vop_read_args *));
     59  1.8  mycroft int	dead_write __P((struct vop_write_args *));
     60  1.8  mycroft int	dead_ioctl __P((struct vop_ioctl_args *));
     61  1.8  mycroft int	dead_select __P((struct vop_select_args *));
     62  1.8  mycroft #define dead_mmap ((int (*) __P((struct  vop_mmap_args *)))dead_badop)
     63  1.8  mycroft #define dead_fsync ((int (*) __P((struct  vop_fsync_args *)))nullop)
     64  1.8  mycroft #define dead_seek ((int (*) __P((struct  vop_seek_args *)))nullop)
     65  1.8  mycroft #define dead_remove ((int (*) __P((struct  vop_remove_args *)))dead_badop)
     66  1.8  mycroft #define dead_link ((int (*) __P((struct  vop_link_args *)))dead_badop)
     67  1.8  mycroft #define dead_rename ((int (*) __P((struct  vop_rename_args *)))dead_badop)
     68  1.8  mycroft #define dead_mkdir ((int (*) __P((struct  vop_mkdir_args *)))dead_badop)
     69  1.8  mycroft #define dead_rmdir ((int (*) __P((struct  vop_rmdir_args *)))dead_badop)
     70  1.8  mycroft #define dead_symlink ((int (*) __P((struct  vop_symlink_args *)))dead_badop)
     71  1.8  mycroft #define dead_readdir ((int (*) __P((struct  vop_readdir_args *)))dead_ebadf)
     72  1.8  mycroft #define dead_readlink ((int (*) __P((struct  vop_readlink_args *)))dead_ebadf)
     73  1.8  mycroft #define dead_abortop ((int (*) __P((struct  vop_abortop_args *)))dead_badop)
     74  1.8  mycroft #define dead_inactive ((int (*) __P((struct  vop_inactive_args *)))nullop)
     75  1.8  mycroft #define dead_reclaim ((int (*) __P((struct  vop_reclaim_args *)))nullop)
     76  1.8  mycroft int	dead_lock __P((struct vop_lock_args *));
     77  1.8  mycroft #define dead_unlock ((int (*) __P((struct  vop_unlock_args *)))nullop)
     78  1.8  mycroft int	dead_bmap __P((struct vop_bmap_args *));
     79  1.8  mycroft int	dead_strategy __P((struct vop_strategy_args *));
     80  1.8  mycroft int	dead_print __P((struct vop_print_args *));
     81  1.8  mycroft #define dead_islocked ((int (*) __P((struct  vop_islocked_args *)))nullop)
     82  1.8  mycroft #define dead_pathconf ((int (*) __P((struct  vop_pathconf_args *)))dead_ebadf)
     83  1.8  mycroft #define dead_advlock ((int (*) __P((struct  vop_advlock_args *)))dead_ebadf)
     84  1.8  mycroft #define dead_blkatoff ((int (*) __P((struct  vop_blkatoff_args *)))dead_badop)
     85  1.8  mycroft #define dead_valloc ((int (*) __P((struct  vop_valloc_args *)))dead_badop)
     86  1.8  mycroft #define dead_vfree ((int (*) __P((struct  vop_vfree_args *)))dead_badop)
     87  1.8  mycroft #define dead_truncate ((int (*) __P((struct  vop_truncate_args *)))nullop)
     88  1.8  mycroft #define dead_update ((int (*) __P((struct  vop_update_args *)))nullop)
     89  1.8  mycroft #define dead_bwrite ((int (*) __P((struct  vop_bwrite_args *)))nullop)
     90  1.8  mycroft 
     91  1.8  mycroft int (**dead_vnodeop_p)();
     92  1.8  mycroft struct vnodeopv_entry_desc dead_vnodeop_entries[] = {
     93  1.8  mycroft 	{ &vop_default_desc, vn_default_error },
     94  1.8  mycroft 	{ &vop_lookup_desc, dead_lookup },	/* lookup */
     95  1.8  mycroft 	{ &vop_create_desc, dead_create },	/* create */
     96  1.8  mycroft 	{ &vop_mknod_desc, dead_mknod },	/* mknod */
     97  1.8  mycroft 	{ &vop_open_desc, dead_open },	/* open */
     98  1.8  mycroft 	{ &vop_close_desc, dead_close },	/* close */
     99  1.8  mycroft 	{ &vop_access_desc, dead_access },	/* access */
    100  1.8  mycroft 	{ &vop_getattr_desc, dead_getattr },	/* getattr */
    101  1.8  mycroft 	{ &vop_setattr_desc, dead_setattr },	/* setattr */
    102  1.8  mycroft 	{ &vop_read_desc, dead_read },	/* read */
    103  1.8  mycroft 	{ &vop_write_desc, dead_write },	/* write */
    104  1.8  mycroft 	{ &vop_ioctl_desc, dead_ioctl },	/* ioctl */
    105  1.8  mycroft 	{ &vop_select_desc, dead_select },	/* select */
    106  1.8  mycroft 	{ &vop_mmap_desc, dead_mmap },	/* mmap */
    107  1.8  mycroft 	{ &vop_fsync_desc, dead_fsync },	/* fsync */
    108  1.8  mycroft 	{ &vop_seek_desc, dead_seek },	/* seek */
    109  1.8  mycroft 	{ &vop_remove_desc, dead_remove },	/* remove */
    110  1.8  mycroft 	{ &vop_link_desc, dead_link },	/* link */
    111  1.8  mycroft 	{ &vop_rename_desc, dead_rename },	/* rename */
    112  1.8  mycroft 	{ &vop_mkdir_desc, dead_mkdir },	/* mkdir */
    113  1.8  mycroft 	{ &vop_rmdir_desc, dead_rmdir },	/* rmdir */
    114  1.8  mycroft 	{ &vop_symlink_desc, dead_symlink },	/* symlink */
    115  1.8  mycroft 	{ &vop_readdir_desc, dead_readdir },	/* readdir */
    116  1.8  mycroft 	{ &vop_readlink_desc, dead_readlink },	/* readlink */
    117  1.8  mycroft 	{ &vop_abortop_desc, dead_abortop },	/* abortop */
    118  1.8  mycroft 	{ &vop_inactive_desc, dead_inactive },	/* inactive */
    119  1.8  mycroft 	{ &vop_reclaim_desc, dead_reclaim },	/* reclaim */
    120  1.8  mycroft 	{ &vop_lock_desc, dead_lock },	/* lock */
    121  1.8  mycroft 	{ &vop_unlock_desc, dead_unlock },	/* unlock */
    122  1.8  mycroft 	{ &vop_bmap_desc, dead_bmap },	/* bmap */
    123  1.8  mycroft 	{ &vop_strategy_desc, dead_strategy },	/* strategy */
    124  1.8  mycroft 	{ &vop_print_desc, dead_print },	/* print */
    125  1.8  mycroft 	{ &vop_islocked_desc, dead_islocked },	/* islocked */
    126  1.8  mycroft 	{ &vop_pathconf_desc, dead_pathconf },	/* pathconf */
    127  1.8  mycroft 	{ &vop_advlock_desc, dead_advlock },	/* advlock */
    128  1.8  mycroft 	{ &vop_blkatoff_desc, dead_blkatoff },	/* blkatoff */
    129  1.8  mycroft 	{ &vop_valloc_desc, dead_valloc },	/* valloc */
    130  1.8  mycroft 	{ &vop_vfree_desc, dead_vfree },	/* vfree */
    131  1.8  mycroft 	{ &vop_truncate_desc, dead_truncate },	/* truncate */
    132  1.8  mycroft 	{ &vop_update_desc, dead_update },	/* update */
    133  1.8  mycroft 	{ &vop_bwrite_desc, dead_bwrite },	/* bwrite */
    134  1.8  mycroft 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
    135  1.1      cgd };
    136  1.8  mycroft struct vnodeopv_desc dead_vnodeop_opv_desc =
    137  1.8  mycroft 	{ &dead_vnodeop_p, dead_vnodeop_entries };
    138  1.1      cgd 
    139  1.1      cgd /*
    140  1.1      cgd  * Trivial lookup routine that always fails.
    141  1.1      cgd  */
    142  1.1      cgd /* ARGSUSED */
    143  1.3   andrew int
    144  1.8  mycroft dead_lookup(ap)
    145  1.8  mycroft 	struct vop_lookup_args /* {
    146  1.8  mycroft 		struct vnode * a_dvp;
    147  1.8  mycroft 		struct vnode ** a_vpp;
    148  1.8  mycroft 		struct componentname * a_cnp;
    149  1.8  mycroft 	} */ *ap;
    150  1.1      cgd {
    151  1.1      cgd 
    152  1.8  mycroft 	*ap->a_vpp = NULL;
    153  1.1      cgd 	return (ENOTDIR);
    154  1.1      cgd }
    155  1.1      cgd 
    156  1.1      cgd /*
    157  1.1      cgd  * Open always fails as if device did not exist.
    158  1.1      cgd  */
    159  1.1      cgd /* ARGSUSED */
    160  1.8  mycroft dead_open(ap)
    161  1.8  mycroft 	struct vop_open_args /* {
    162  1.8  mycroft 		struct vnode *a_vp;
    163  1.8  mycroft 		int  a_mode;
    164  1.8  mycroft 		struct ucred *a_cred;
    165  1.8  mycroft 		struct proc *a_p;
    166  1.8  mycroft 	} */ *ap;
    167  1.1      cgd {
    168  1.1      cgd 
    169  1.1      cgd 	return (ENXIO);
    170  1.1      cgd }
    171  1.1      cgd 
    172  1.1      cgd /*
    173  1.1      cgd  * Vnode op for read
    174  1.1      cgd  */
    175  1.1      cgd /* ARGSUSED */
    176  1.8  mycroft dead_read(ap)
    177  1.8  mycroft 	struct vop_read_args /* {
    178  1.8  mycroft 		struct vnode *a_vp;
    179  1.8  mycroft 		struct uio *a_uio;
    180  1.8  mycroft 		int  a_ioflag;
    181  1.8  mycroft 		struct ucred *a_cred;
    182  1.8  mycroft 	} */ *ap;
    183  1.1      cgd {
    184  1.1      cgd 
    185  1.8  mycroft 	if (chkvnlock(ap->a_vp))
    186  1.1      cgd 		panic("dead_read: lock");
    187  1.1      cgd 	/*
    188  1.1      cgd 	 * Return EOF for character devices, EIO for others
    189  1.1      cgd 	 */
    190  1.8  mycroft 	if (ap->a_vp->v_type != VCHR)
    191  1.1      cgd 		return (EIO);
    192  1.1      cgd 	return (0);
    193  1.1      cgd }
    194  1.1      cgd 
    195  1.1      cgd /*
    196  1.1      cgd  * Vnode op for write
    197  1.1      cgd  */
    198  1.1      cgd /* ARGSUSED */
    199  1.8  mycroft dead_write(ap)
    200  1.8  mycroft 	struct vop_write_args /* {
    201  1.8  mycroft 		struct vnode *a_vp;
    202  1.8  mycroft 		struct uio *a_uio;
    203  1.8  mycroft 		int  a_ioflag;
    204  1.8  mycroft 		struct ucred *a_cred;
    205  1.8  mycroft 	} */ *ap;
    206  1.1      cgd {
    207  1.1      cgd 
    208  1.8  mycroft 	if (chkvnlock(ap->a_vp))
    209  1.1      cgd 		panic("dead_write: lock");
    210  1.1      cgd 	return (EIO);
    211  1.1      cgd }
    212  1.1      cgd 
    213  1.1      cgd /*
    214  1.1      cgd  * Device ioctl operation.
    215  1.1      cgd  */
    216  1.1      cgd /* ARGSUSED */
    217  1.8  mycroft dead_ioctl(ap)
    218  1.8  mycroft 	struct vop_ioctl_args /* {
    219  1.8  mycroft 		struct vnode *a_vp;
    220  1.8  mycroft 		int  a_command;
    221  1.8  mycroft 		caddr_t  a_data;
    222  1.8  mycroft 		int  a_fflag;
    223  1.8  mycroft 		struct ucred *a_cred;
    224  1.8  mycroft 		struct proc *a_p;
    225  1.8  mycroft 	} */ *ap;
    226  1.1      cgd {
    227  1.1      cgd 
    228  1.8  mycroft 	if (!chkvnlock(ap->a_vp))
    229  1.1      cgd 		return (EBADF);
    230  1.8  mycroft 	return (VCALL(ap->a_vp, VOFFSET(vop_ioctl), ap));
    231  1.1      cgd }
    232  1.1      cgd 
    233  1.1      cgd /* ARGSUSED */
    234  1.8  mycroft dead_select(ap)
    235  1.8  mycroft 	struct vop_select_args /* {
    236  1.8  mycroft 		struct vnode *a_vp;
    237  1.8  mycroft 		int  a_which;
    238  1.8  mycroft 		int  a_fflags;
    239  1.8  mycroft 		struct ucred *a_cred;
    240  1.8  mycroft 		struct proc *a_p;
    241  1.8  mycroft 	} */ *ap;
    242  1.1      cgd {
    243  1.1      cgd 
    244  1.1      cgd 	/*
    245  1.1      cgd 	 * Let the user find out that the descriptor is gone.
    246  1.1      cgd 	 */
    247  1.1      cgd 	return (1);
    248  1.1      cgd }
    249  1.1      cgd 
    250  1.1      cgd /*
    251  1.1      cgd  * Just call the device strategy routine
    252  1.1      cgd  */
    253  1.8  mycroft dead_strategy(ap)
    254  1.8  mycroft 	struct vop_strategy_args /* {
    255  1.8  mycroft 		struct buf *a_bp;
    256  1.8  mycroft 	} */ *ap;
    257  1.1      cgd {
    258  1.1      cgd 
    259  1.8  mycroft 	if (ap->a_bp->b_vp == NULL || !chkvnlock(ap->a_bp->b_vp)) {
    260  1.8  mycroft 		ap->a_bp->b_flags |= B_ERROR;
    261  1.8  mycroft 		biodone(ap->a_bp);
    262  1.1      cgd 		return (EIO);
    263  1.1      cgd 	}
    264  1.8  mycroft 	return (VOP_STRATEGY(ap->a_bp));
    265  1.1      cgd }
    266  1.1      cgd 
    267  1.1      cgd /*
    268  1.1      cgd  * Wait until the vnode has finished changing state.
    269  1.1      cgd  */
    270  1.8  mycroft dead_lock(ap)
    271  1.8  mycroft 	struct vop_lock_args /* {
    272  1.8  mycroft 		struct vnode *a_vp;
    273  1.8  mycroft 	} */ *ap;
    274  1.1      cgd {
    275  1.1      cgd 
    276  1.8  mycroft 	if (!chkvnlock(ap->a_vp))
    277  1.1      cgd 		return (0);
    278  1.8  mycroft 	return (VCALL(ap->a_vp, VOFFSET(vop_lock), ap));
    279  1.1      cgd }
    280  1.1      cgd 
    281  1.1      cgd /*
    282  1.1      cgd  * Wait until the vnode has finished changing state.
    283  1.1      cgd  */
    284  1.8  mycroft dead_bmap(ap)
    285  1.8  mycroft 	struct vop_bmap_args /* {
    286  1.8  mycroft 		struct vnode *a_vp;
    287  1.8  mycroft 		daddr_t  a_bn;
    288  1.8  mycroft 		struct vnode **a_vpp;
    289  1.8  mycroft 		daddr_t *a_bnp;
    290  1.8  mycroft 		int *a_runp;
    291  1.8  mycroft 	} */ *ap;
    292  1.1      cgd {
    293  1.1      cgd 
    294  1.8  mycroft 	if (!chkvnlock(ap->a_vp))
    295  1.1      cgd 		return (EIO);
    296  1.8  mycroft 	return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp));
    297  1.1      cgd }
    298  1.1      cgd 
    299  1.1      cgd /*
    300  1.1      cgd  * Print out the contents of a dead vnode.
    301  1.1      cgd  */
    302  1.1      cgd /* ARGSUSED */
    303  1.8  mycroft dead_print(ap)
    304  1.8  mycroft 	struct vop_print_args /* {
    305  1.8  mycroft 		struct vnode *a_vp;
    306  1.8  mycroft 	} */ *ap;
    307  1.1      cgd {
    308  1.1      cgd 
    309  1.1      cgd 	printf("tag VT_NON, dead vnode\n");
    310  1.1      cgd }
    311  1.1      cgd 
    312  1.1      cgd /*
    313  1.1      cgd  * Empty vnode failed operation
    314  1.1      cgd  */
    315  1.1      cgd dead_ebadf()
    316  1.1      cgd {
    317  1.1      cgd 
    318  1.1      cgd 	return (EBADF);
    319  1.1      cgd }
    320  1.1      cgd 
    321  1.1      cgd /*
    322  1.1      cgd  * Empty vnode bad operation
    323  1.1      cgd  */
    324  1.1      cgd dead_badop()
    325  1.1      cgd {
    326  1.1      cgd 
    327  1.1      cgd 	panic("dead_badop called");
    328  1.1      cgd 	/* NOTREACHED */
    329  1.1      cgd }
    330  1.1      cgd 
    331  1.1      cgd /*
    332  1.1      cgd  * Empty vnode null operation
    333  1.1      cgd  */
    334  1.1      cgd dead_nullop()
    335  1.1      cgd {
    336  1.1      cgd 
    337  1.1      cgd 	return (0);
    338  1.1      cgd }
    339  1.1      cgd 
    340  1.1      cgd /*
    341  1.1      cgd  * We have to wait during times when the vnode is
    342  1.1      cgd  * in a state of change.
    343  1.1      cgd  */
    344  1.1      cgd chkvnlock(vp)
    345  1.1      cgd 	register struct vnode *vp;
    346  1.1      cgd {
    347  1.1      cgd 	int locked = 0;
    348  1.1      cgd 
    349  1.1      cgd 	while (vp->v_flag & VXLOCK) {
    350  1.1      cgd 		vp->v_flag |= VXWANT;
    351  1.8  mycroft 		sleep((caddr_t)vp, PINOD);
    352  1.1      cgd 		locked = 1;
    353  1.1      cgd 	}
    354  1.1      cgd 	return (locked);
    355  1.1      cgd }
    356