Home | History | Annotate | Line # | Download | only in deadfs
dead_vnops.c revision 1.1
      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 }
    418