xref: /csrg-svn/sys/miscfs/deadfs/dead_vnops.c (revision 51565)
139483Smckusick /*
239483Smckusick  * Copyright (c) 1989 The Regents of the University of California.
339483Smckusick  * All rights reserved.
439483Smckusick  *
544429Sbostic  * %sccs.include.redist.c%
639483Smckusick  *
7*51565Smckusick  *	@(#)dead_vnops.c	7.14 (Berkeley) 11/05/91
839483Smckusick  */
939483Smckusick 
1039483Smckusick #include "param.h"
1148012Smckusick #include "systm.h"
1239483Smckusick #include "time.h"
1339483Smckusick #include "vnode.h"
1439483Smckusick #include "errno.h"
1539483Smckusick #include "namei.h"
1639483Smckusick #include "buf.h"
1739483Smckusick 
1848012Smckusick /*
1948012Smckusick  * Prototypes for dead operations on vnodes.
2048012Smckusick  */
2148012Smckusick int	dead_badop(),
2248012Smckusick 	dead_ebadf();
2348012Smckusick int	dead_lookup __P((
2448012Smckusick 		struct vnode *vp,
2548012Smckusick 		struct nameidata *ndp,
2648012Smckusick 		struct proc *p));
2748012Smckusick #define dead_create ((int (*) __P(( \
2848012Smckusick 		struct nameidata *ndp, \
2948012Smckusick 		struct vattr *vap, \
3048012Smckusick 		struct proc *p))) dead_badop)
3148012Smckusick #define dead_mknod ((int (*) __P(( \
3248012Smckusick 		struct nameidata *ndp, \
3348012Smckusick 		struct vattr *vap, \
3448012Smckusick 		struct ucred *cred, \
3548012Smckusick 		struct proc *p))) dead_badop)
3648012Smckusick int	dead_open __P((
3748012Smckusick 		struct vnode *vp,
3848012Smckusick 		int mode,
3948012Smckusick 		struct ucred *cred,
4048012Smckusick 		struct proc *p));
4148012Smckusick #define dead_close ((int (*) __P(( \
4248012Smckusick 		struct vnode *vp, \
4348012Smckusick 		int fflag, \
4448012Smckusick 		struct ucred *cred, \
4548012Smckusick 		struct proc *p))) nullop)
4648012Smckusick #define dead_access ((int (*) __P(( \
4748012Smckusick 		struct vnode *vp, \
4848012Smckusick 		int mode, \
4948012Smckusick 		struct ucred *cred, \
5048012Smckusick 		struct proc *p))) dead_ebadf)
5148012Smckusick #define dead_getattr ((int (*) __P(( \
5248012Smckusick 		struct vnode *vp, \
5348012Smckusick 		struct vattr *vap, \
5448012Smckusick 		struct ucred *cred, \
5548012Smckusick 		struct proc *p))) dead_ebadf)
5648012Smckusick #define dead_setattr ((int (*) __P(( \
5748012Smckusick 		struct vnode *vp, \
5848012Smckusick 		struct vattr *vap, \
5948012Smckusick 		struct ucred *cred, \
6048012Smckusick 		struct proc *p))) dead_ebadf)
6148012Smckusick int	dead_read __P((
6248012Smckusick 		struct vnode *vp,
6348012Smckusick 		struct uio *uio,
6448012Smckusick 		int ioflag,
6548012Smckusick 		struct ucred *cred));
6648012Smckusick int	dead_write __P((
6748012Smckusick 		struct vnode *vp,
6848012Smckusick 		struct uio *uio,
6948012Smckusick 		int ioflag,
7048012Smckusick 		struct ucred *cred));
7148012Smckusick int	dead_ioctl __P((
7248012Smckusick 		struct vnode *vp,
7348012Smckusick 		int command,
7448012Smckusick 		caddr_t data,
7548012Smckusick 		int fflag,
7648012Smckusick 		struct ucred *cred,
7748012Smckusick 		struct proc *p));
7848012Smckusick int	dead_select __P((
7948012Smckusick 		struct vnode *vp,
8048012Smckusick 		int which,
8148012Smckusick 		int fflags,
8248012Smckusick 		struct ucred *cred,
8348012Smckusick 		struct proc *p));
8448012Smckusick #define dead_mmap ((int (*) __P(( \
8548012Smckusick 		struct vnode *vp, \
8648012Smckusick 		int fflags, \
8748012Smckusick 		struct ucred *cred, \
8848012Smckusick 		struct proc *p))) dead_badop)
8948012Smckusick #define dead_fsync ((int (*) __P(( \
9048012Smckusick 		struct vnode *vp, \
9148012Smckusick 		int fflags, \
9248012Smckusick 		struct ucred *cred, \
9348012Smckusick 		int waitfor, \
9448012Smckusick 		struct proc *p))) nullop)
9548012Smckusick #define dead_seek ((int (*) __P(( \
9648012Smckusick 		struct vnode *vp, \
9748012Smckusick 		off_t oldoff, \
9848012Smckusick 		off_t newoff, \
9948012Smckusick 		struct ucred *cred))) nullop)
10048012Smckusick #define dead_remove ((int (*) __P(( \
10148012Smckusick 		struct nameidata *ndp, \
10248012Smckusick 		struct proc *p))) dead_badop)
10348012Smckusick #define dead_link ((int (*) __P(( \
10448012Smckusick 		struct vnode *vp, \
10548012Smckusick 		struct nameidata *ndp, \
10648012Smckusick 		struct proc *p))) dead_badop)
10748012Smckusick #define dead_rename ((int (*) __P(( \
10848012Smckusick 		struct nameidata *fndp, \
10948012Smckusick 		struct nameidata *tdnp, \
11048012Smckusick 		struct proc *p))) dead_badop)
11148012Smckusick #define dead_mkdir ((int (*) __P(( \
11248012Smckusick 		struct nameidata *ndp, \
11348012Smckusick 		struct vattr *vap, \
11448012Smckusick 		struct proc *p))) dead_badop)
11548012Smckusick #define dead_rmdir ((int (*) __P(( \
11648012Smckusick 		struct nameidata *ndp, \
11748012Smckusick 		struct proc *p))) dead_badop)
11848012Smckusick #define dead_symlink ((int (*) __P(( \
11948012Smckusick 		struct nameidata *ndp, \
12048012Smckusick 		struct vattr *vap, \
12148012Smckusick 		char *target, \
12248012Smckusick 		struct proc *p))) dead_badop)
12348012Smckusick #define dead_readdir ((int (*) __P(( \
12448012Smckusick 		struct vnode *vp, \
12548012Smckusick 		struct uio *uio, \
12648012Smckusick 		struct ucred *cred, \
12748012Smckusick 		int *eofflagp))) dead_ebadf)
12848012Smckusick #define dead_readlink ((int (*) __P(( \
12948012Smckusick 		struct vnode *vp, \
13048012Smckusick 		struct uio *uio, \
13148012Smckusick 		struct ucred *cred))) dead_ebadf)
13248012Smckusick #define dead_abortop ((int (*) __P(( \
13348012Smckusick 		struct nameidata *ndp))) dead_badop)
13448012Smckusick #define dead_inactive ((int (*) __P(( \
13548012Smckusick 		struct vnode *vp, \
13648012Smckusick 		struct proc *p))) nullop)
13748012Smckusick #define dead_reclaim ((int (*) __P(( \
13848012Smckusick 		struct vnode *vp))) nullop)
13948012Smckusick int	dead_lock __P((
14048012Smckusick 		struct vnode *vp));
14148012Smckusick #define dead_unlock ((int (*) __P(( \
14248012Smckusick 		struct vnode *vp))) nullop)
14348012Smckusick int	dead_bmap __P((
14448012Smckusick 		struct vnode *vp,
14548012Smckusick 		daddr_t bn,
14648012Smckusick 		struct vnode **vpp,
14748012Smckusick 		daddr_t *bnp));
14848012Smckusick int	dead_strategy __P((
14948012Smckusick 		struct buf *bp));
15048012Smckusick int	dead_print __P((
15148012Smckusick 		struct vnode *vp));
15248012Smckusick #define dead_islocked ((int (*) __P(( \
15348012Smckusick 		struct vnode *vp))) nullop)
15448012Smckusick #define dead_advlock ((int (*) __P(( \
15548012Smckusick 		struct vnode *vp, \
15648012Smckusick 		caddr_t id, \
15748012Smckusick 		int op, \
15848012Smckusick 		struct flock *fl, \
15948012Smckusick 		int flags))) dead_ebadf)
160*51565Smckusick #define dead_blkatoff ((int (*) __P(( \
161*51565Smckusick 		struct vnode *vp, \
162*51565Smckusick 		off_t offset, \
163*51565Smckusick 		char **res, \
164*51565Smckusick 		struct buf **bpp))) dead_badop)
165*51565Smckusick #define dead_vget ((int (*) __P(( \
166*51565Smckusick 		struct mount *mp, \
167*51565Smckusick 		ino_t ino, \
168*51565Smckusick 		struct vnode **vpp))) dead_badop)
169*51565Smckusick #define dead_valloc ((int (*) __P(( \
170*51565Smckusick 		struct vnode *pvp, \
171*51565Smckusick 		int mode, \
172*51565Smckusick 		struct ucred *cred, \
173*51565Smckusick 		struct vnode **vpp))) dead_badop)
174*51565Smckusick #define dead_vfree ((void (*) __P(( \
175*51565Smckusick 		struct vnode *pvp, \
176*51565Smckusick 		ino_t ino, \
177*51565Smckusick 		int mode))) dead_badop)
178*51565Smckusick #define dead_truncate ((int (*) __P(( \
179*51565Smckusick 		struct vnode *vp, \
180*51565Smckusick 		u_long length, \
181*51565Smckusick 		int flags))) nullop)
182*51565Smckusick #define dead_update ((int (*) __P(( \
183*51565Smckusick 		struct vnode *vp, \
184*51565Smckusick 		struct timeval *ta, \
185*51565Smckusick 		struct timeval *tm, \
186*51565Smckusick 		int waitfor))) nullop)
187*51565Smckusick #define dead_bwrite ((int (*) __P(( \
188*51565Smckusick 		struct buf *bp))) nullop)
18939483Smckusick 
19039483Smckusick struct vnodeops dead_vnodeops = {
19139483Smckusick 	dead_lookup,	/* lookup */
19248012Smckusick 	dead_create,	/* create */
19348012Smckusick 	dead_mknod,	/* mknod */
19439483Smckusick 	dead_open,	/* open */
19548012Smckusick 	dead_close,	/* close */
19648012Smckusick 	dead_access,	/* access */
19748012Smckusick 	dead_getattr,	/* getattr */
19848012Smckusick 	dead_setattr,	/* setattr */
19939483Smckusick 	dead_read,	/* read */
20039483Smckusick 	dead_write,	/* write */
20139483Smckusick 	dead_ioctl,	/* ioctl */
20239483Smckusick 	dead_select,	/* select */
20348012Smckusick 	dead_mmap,	/* mmap */
20448012Smckusick 	dead_fsync,	/* fsync */
20548012Smckusick 	dead_seek,	/* seek */
20648012Smckusick 	dead_remove,	/* remove */
20748012Smckusick 	dead_link,	/* link */
20848012Smckusick 	dead_rename,	/* rename */
20948012Smckusick 	dead_mkdir,	/* mkdir */
21048012Smckusick 	dead_rmdir,	/* rmdir */
21148012Smckusick 	dead_symlink,	/* symlink */
21248012Smckusick 	dead_readdir,	/* readdir */
21348012Smckusick 	dead_readlink,	/* readlink */
21448012Smckusick 	dead_abortop,	/* abortop */
21548012Smckusick 	dead_inactive,	/* inactive */
21648012Smckusick 	dead_reclaim,	/* reclaim */
21739483Smckusick 	dead_lock,	/* lock */
21848012Smckusick 	dead_unlock,	/* unlock */
21939508Smckusick 	dead_bmap,	/* bmap */
22039483Smckusick 	dead_strategy,	/* strategy */
22139911Smckusick 	dead_print,	/* print */
22248012Smckusick 	dead_islocked,	/* islocked */
22348012Smckusick 	dead_advlock,	/* advlock */
224*51565Smckusick 	dead_blkatoff,	/* blkatoff */
225*51565Smckusick 	dead_vget,	/* vget */
226*51565Smckusick 	dead_valloc,	/* valloc */
227*51565Smckusick 	dead_vfree,	/* vfree */
228*51565Smckusick 	dead_truncate,	/* truncate */
229*51565Smckusick 	dead_update,	/* update */
230*51565Smckusick 	dead_bwrite,	/* bwrite */
23139483Smckusick };
23239483Smckusick 
23339483Smckusick /*
23439483Smckusick  * Trivial lookup routine that always fails.
23539483Smckusick  */
23648012Smckusick /* ARGSUSED */
23748012Smckusick dead_lookup(vp, ndp, p)
23839483Smckusick 	struct vnode *vp;
23939483Smckusick 	struct nameidata *ndp;
24048012Smckusick 	struct proc *p;
24139483Smckusick {
24239483Smckusick 
24339483Smckusick 	ndp->ni_dvp = vp;
24439483Smckusick 	ndp->ni_vp = NULL;
24539483Smckusick 	return (ENOTDIR);
24639483Smckusick }
24739483Smckusick 
24839483Smckusick /*
24939483Smckusick  * Open always fails as if device did not exist.
25039483Smckusick  */
25139483Smckusick /* ARGSUSED */
25248012Smckusick dead_open(vp, mode, cred, p)
25339483Smckusick 	struct vnode *vp;
25439483Smckusick 	int mode;
25539483Smckusick 	struct ucred *cred;
25648012Smckusick 	struct proc *p;
25739483Smckusick {
25839483Smckusick 
25939483Smckusick 	return (ENXIO);
26039483Smckusick }
26139483Smckusick 
26239483Smckusick /*
26339483Smckusick  * Vnode op for read
26439483Smckusick  */
26539591Smckusick /* ARGSUSED */
26639591Smckusick dead_read(vp, uio, ioflag, cred)
26739483Smckusick 	struct vnode *vp;
26839483Smckusick 	struct uio *uio;
26939483Smckusick 	int ioflag;
27039483Smckusick 	struct ucred *cred;
27139483Smckusick {
27239483Smckusick 
27339591Smckusick 	if (chkvnlock(vp))
27439591Smckusick 		panic("dead_read: lock");
27539591Smckusick 	/*
27639591Smckusick 	 * Return EOF for character devices, EIO for others
27739591Smckusick 	 */
27839591Smckusick 	if (vp->v_type != VCHR)
27939483Smckusick 		return (EIO);
28039591Smckusick 	return (0);
28139483Smckusick }
28239483Smckusick 
28339483Smckusick /*
28439483Smckusick  * Vnode op for write
28539483Smckusick  */
28639591Smckusick /* ARGSUSED */
28739591Smckusick dead_write(vp, uio, ioflag, cred)
28839483Smckusick 	register struct vnode *vp;
28939483Smckusick 	struct uio *uio;
29039483Smckusick 	int ioflag;
29139483Smckusick 	struct ucred *cred;
29239483Smckusick {
29339483Smckusick 
29439591Smckusick 	if (chkvnlock(vp))
29539591Smckusick 		panic("dead_write: lock");
29639591Smckusick 	return (EIO);
29739483Smckusick }
29839483Smckusick 
29939483Smckusick /*
30039483Smckusick  * Device ioctl operation.
30139483Smckusick  */
30239483Smckusick /* ARGSUSED */
30348012Smckusick dead_ioctl(vp, com, data, fflag, cred, p)
30439483Smckusick 	struct vnode *vp;
30539483Smckusick 	register int com;
30639483Smckusick 	caddr_t data;
30739483Smckusick 	int fflag;
30839483Smckusick 	struct ucred *cred;
30948012Smckusick 	struct proc *p;
31039483Smckusick {
31139483Smckusick 
31239519Smckusick 	if (!chkvnlock(vp))
31339483Smckusick 		return (EBADF);
31448012Smckusick 	return (VOP_IOCTL(vp, com, data, fflag, cred, p));
31539483Smckusick }
31639483Smckusick 
31739483Smckusick /* ARGSUSED */
31848012Smckusick dead_select(vp, which, fflags, cred, p)
31939483Smckusick 	struct vnode *vp;
32040188Smckusick 	int which, fflags;
32139483Smckusick 	struct ucred *cred;
32248012Smckusick 	struct proc *p;
32339483Smckusick {
32439483Smckusick 
32539483Smckusick 	/*
32639483Smckusick 	 * Let the user find out that the descriptor is gone.
32739483Smckusick 	 */
32839483Smckusick 	return (1);
32939483Smckusick }
33039483Smckusick 
33139483Smckusick /*
33239483Smckusick  * Just call the device strategy routine
33339483Smckusick  */
33439483Smckusick dead_strategy(bp)
33539483Smckusick 	register struct buf *bp;
33639483Smckusick {
33739483Smckusick 
33839519Smckusick 	if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) {
33939518Smckusick 		bp->b_flags |= B_ERROR;
34039853Smckusick 		biodone(bp);
34139483Smckusick 		return (EIO);
34239518Smckusick 	}
34339483Smckusick 	return (VOP_STRATEGY(bp));
34439483Smckusick }
34539483Smckusick 
34639483Smckusick /*
34739483Smckusick  * Wait until the vnode has finished changing state.
34839483Smckusick  */
34939483Smckusick dead_lock(vp)
35039483Smckusick 	struct vnode *vp;
35139483Smckusick {
35239483Smckusick 
35339519Smckusick 	if (!chkvnlock(vp))
35439483Smckusick 		return (0);
35539483Smckusick 	return (VOP_LOCK(vp));
35639483Smckusick }
35739483Smckusick 
35839483Smckusick /*
35939508Smckusick  * Wait until the vnode has finished changing state.
36039508Smckusick  */
36139508Smckusick dead_bmap(vp, bn, vpp, bnp)
36239508Smckusick 	struct vnode *vp;
36339508Smckusick 	daddr_t bn;
36439508Smckusick 	struct vnode **vpp;
36539508Smckusick 	daddr_t *bnp;
36639508Smckusick {
36739508Smckusick 
36839519Smckusick 	if (!chkvnlock(vp))
36939508Smckusick 		return (EIO);
37039508Smckusick 	return (VOP_BMAP(vp, bn, vpp, bnp));
37139508Smckusick }
37239508Smckusick 
37339508Smckusick /*
37439911Smckusick  * Print out the contents of a dead vnode.
37539911Smckusick  */
37645110Smckusick /* ARGSUSED */
37739911Smckusick dead_print(vp)
37839911Smckusick 	struct vnode *vp;
37939911Smckusick {
38039911Smckusick 
38139911Smckusick 	printf("tag VT_NON, dead vnode\n");
38239911Smckusick }
38339911Smckusick 
38439911Smckusick /*
38539486Smckusick  * Empty vnode failed operation
38639486Smckusick  */
38739486Smckusick dead_ebadf()
38839486Smckusick {
38939486Smckusick 
39039486Smckusick 	return (EBADF);
39139486Smckusick }
39239486Smckusick 
39339486Smckusick /*
39439483Smckusick  * Empty vnode bad operation
39539483Smckusick  */
39639483Smckusick dead_badop()
39739483Smckusick {
39839483Smckusick 
39939483Smckusick 	panic("dead_badop called");
40039483Smckusick 	/* NOTREACHED */
40139483Smckusick }
40239483Smckusick 
40339483Smckusick /*
40439483Smckusick  * Empty vnode null operation
40539483Smckusick  */
40639483Smckusick dead_nullop()
40739483Smckusick {
40839483Smckusick 
40939483Smckusick 	return (0);
41039483Smckusick }
41139519Smckusick 
41239519Smckusick /*
41339519Smckusick  * We have to wait during times when the vnode is
41439519Smckusick  * in a state of change.
41539519Smckusick  */
41639519Smckusick chkvnlock(vp)
41739519Smckusick 	register struct vnode *vp;
41839519Smckusick {
41939519Smckusick 	int locked = 0;
42039519Smckusick 
42139519Smckusick 	while (vp->v_flag & VXLOCK) {
42239519Smckusick 		vp->v_flag |= VXWANT;
42339519Smckusick 		sleep((caddr_t)vp, PINOD);
42439519Smckusick 		locked = 1;
42539519Smckusick 	}
42639519Smckusick 	return (locked);
42739519Smckusick }
428