xref: /csrg-svn/sys/miscfs/deadfs/dead_vnops.c (revision 52303)
139483Smckusick /*
239483Smckusick  * Copyright (c) 1989 The Regents of the University of California.
339483Smckusick  * All rights reserved.
439483Smckusick  *
544429Sbostic  * %sccs.include.redist.c%
639483Smckusick  *
7*52303Sheideman  *	@(#)dead_vnops.c	7.15 (Berkeley) 02/03/92
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((
24*52303Sheideman 		struct vnode *dvp,
25*52303Sheideman 		struct vnode **vpp,
26*52303Sheideman 		struct componentname *cnp));
2748012Smckusick #define dead_create ((int (*) __P(( \
28*52303Sheideman 		struct vnode *dvp, \
29*52303Sheideman  		struct vnode **vpp, \
30*52303Sheideman 		struct componentname *cnp, \
31*52303Sheideman 		struct vattr *vap))) dead_badop)
3248012Smckusick #define dead_mknod ((int (*) __P(( \
33*52303Sheideman 		struct vnode *dvp, \
34*52303Sheideman 		struct vnode **vpp, \
35*52303Sheideman 		struct componentname *cnp, \
36*52303Sheideman 		struct vattr *vap))) dead_badop)
3748012Smckusick int	dead_open __P((
3848012Smckusick 		struct vnode *vp,
3948012Smckusick 		int mode,
4048012Smckusick 		struct ucred *cred,
4148012Smckusick 		struct proc *p));
4248012Smckusick #define dead_close ((int (*) __P(( \
4348012Smckusick 		struct vnode *vp, \
4448012Smckusick 		int fflag, \
4548012Smckusick 		struct ucred *cred, \
4648012Smckusick 		struct proc *p))) nullop)
4748012Smckusick #define dead_access ((int (*) __P(( \
4848012Smckusick 		struct vnode *vp, \
4948012Smckusick 		int mode, \
5048012Smckusick 		struct ucred *cred, \
5148012Smckusick 		struct proc *p))) dead_ebadf)
5248012Smckusick #define dead_getattr ((int (*) __P(( \
5348012Smckusick 		struct vnode *vp, \
5448012Smckusick 		struct vattr *vap, \
5548012Smckusick 		struct ucred *cred, \
5648012Smckusick 		struct proc *p))) dead_ebadf)
5748012Smckusick #define dead_setattr ((int (*) __P(( \
5848012Smckusick 		struct vnode *vp, \
5948012Smckusick 		struct vattr *vap, \
6048012Smckusick 		struct ucred *cred, \
6148012Smckusick 		struct proc *p))) dead_ebadf)
6248012Smckusick int	dead_read __P((
6348012Smckusick 		struct vnode *vp,
6448012Smckusick 		struct uio *uio,
6548012Smckusick 		int ioflag,
6648012Smckusick 		struct ucred *cred));
6748012Smckusick int	dead_write __P((
6848012Smckusick 		struct vnode *vp,
6948012Smckusick 		struct uio *uio,
7048012Smckusick 		int ioflag,
7148012Smckusick 		struct ucred *cred));
7248012Smckusick int	dead_ioctl __P((
7348012Smckusick 		struct vnode *vp,
7448012Smckusick 		int command,
7548012Smckusick 		caddr_t data,
7648012Smckusick 		int fflag,
7748012Smckusick 		struct ucred *cred,
7848012Smckusick 		struct proc *p));
7948012Smckusick int	dead_select __P((
8048012Smckusick 		struct vnode *vp,
8148012Smckusick 		int which,
8248012Smckusick 		int fflags,
8348012Smckusick 		struct ucred *cred,
8448012Smckusick 		struct proc *p));
8548012Smckusick #define dead_mmap ((int (*) __P(( \
8648012Smckusick 		struct vnode *vp, \
8748012Smckusick 		int fflags, \
8848012Smckusick 		struct ucred *cred, \
8948012Smckusick 		struct proc *p))) dead_badop)
9048012Smckusick #define dead_fsync ((int (*) __P(( \
9148012Smckusick 		struct vnode *vp, \
9248012Smckusick 		int fflags, \
9348012Smckusick 		struct ucred *cred, \
9448012Smckusick 		int waitfor, \
9548012Smckusick 		struct proc *p))) nullop)
9648012Smckusick #define dead_seek ((int (*) __P(( \
9748012Smckusick 		struct vnode *vp, \
9848012Smckusick 		off_t oldoff, \
9948012Smckusick 		off_t newoff, \
10048012Smckusick 		struct ucred *cred))) nullop)
10148012Smckusick #define dead_remove ((int (*) __P(( \
102*52303Sheideman 		struct vnode *dvp, \
103*52303Sheideman 	        struct vnode *vp, \
104*52303Sheideman 		struct componentname *cnp))) dead_badop)
10548012Smckusick #define dead_link ((int (*) __P(( \
106*52303Sheideman 		register struct vnode *vp, \
107*52303Sheideman 		struct vnode *tdvp, \
108*52303Sheideman 		struct componentname *cnp))) dead_badop)
10948012Smckusick #define dead_rename ((int (*) __P(( \
110*52303Sheideman 		struct vnode *fdvp, \
111*52303Sheideman 	        struct vnode *fvp, \
112*52303Sheideman 		struct componentname *fcnp, \
113*52303Sheideman 		struct vnode *tdvp, \
114*52303Sheideman 		struct vnode *tvp, \
115*52303Sheideman 		struct componentname *tcnp))) dead_badop)
11648012Smckusick #define dead_mkdir ((int (*) __P(( \
117*52303Sheideman 		struct vnode *dvp, \
118*52303Sheideman 		struct vnode **vpp, \
119*52303Sheideman 		struct componentname *cnp, \
120*52303Sheideman 		struct vattr *vap))) dead_badop)
12148012Smckusick #define dead_rmdir ((int (*) __P(( \
122*52303Sheideman 		struct vnode *dvp, \
123*52303Sheideman 		struct vnode *vp, \
124*52303Sheideman 		struct componentname *cnp))) dead_badop)
12548012Smckusick #define dead_symlink ((int (*) __P(( \
126*52303Sheideman 		struct vnode *dvp, \
127*52303Sheideman 		struct vnode **vpp, \
128*52303Sheideman 		struct componentname *cnp, \
12948012Smckusick 		struct vattr *vap, \
130*52303Sheideman 		char *target))) dead_badop)
13148012Smckusick #define dead_readdir ((int (*) __P(( \
13248012Smckusick 		struct vnode *vp, \
13348012Smckusick 		struct uio *uio, \
13448012Smckusick 		struct ucred *cred, \
13548012Smckusick 		int *eofflagp))) dead_ebadf)
13648012Smckusick #define dead_readlink ((int (*) __P(( \
13748012Smckusick 		struct vnode *vp, \
13848012Smckusick 		struct uio *uio, \
13948012Smckusick 		struct ucred *cred))) dead_ebadf)
14048012Smckusick #define dead_abortop ((int (*) __P(( \
141*52303Sheideman 		struct vnode *dvp, \
142*52303Sheideman 		struct componentname *cnp))) dead_badop)
14348012Smckusick #define dead_inactive ((int (*) __P(( \
14448012Smckusick 		struct vnode *vp, \
14548012Smckusick 		struct proc *p))) nullop)
14648012Smckusick #define dead_reclaim ((int (*) __P(( \
14748012Smckusick 		struct vnode *vp))) nullop)
14848012Smckusick int	dead_lock __P((
14948012Smckusick 		struct vnode *vp));
15048012Smckusick #define dead_unlock ((int (*) __P(( \
15148012Smckusick 		struct vnode *vp))) nullop)
15248012Smckusick int	dead_bmap __P((
15348012Smckusick 		struct vnode *vp,
15448012Smckusick 		daddr_t bn,
15548012Smckusick 		struct vnode **vpp,
15648012Smckusick 		daddr_t *bnp));
15748012Smckusick int	dead_strategy __P((
15848012Smckusick 		struct buf *bp));
15948012Smckusick int	dead_print __P((
16048012Smckusick 		struct vnode *vp));
16148012Smckusick #define dead_islocked ((int (*) __P(( \
16248012Smckusick 		struct vnode *vp))) nullop)
16348012Smckusick #define dead_advlock ((int (*) __P(( \
16448012Smckusick 		struct vnode *vp, \
16548012Smckusick 		caddr_t id, \
16648012Smckusick 		int op, \
16748012Smckusick 		struct flock *fl, \
16848012Smckusick 		int flags))) dead_ebadf)
16951565Smckusick #define dead_blkatoff ((int (*) __P(( \
17051565Smckusick 		struct vnode *vp, \
17151565Smckusick 		off_t offset, \
17251565Smckusick 		char **res, \
17351565Smckusick 		struct buf **bpp))) dead_badop)
17451565Smckusick #define dead_vget ((int (*) __P(( \
17551565Smckusick 		struct mount *mp, \
17651565Smckusick 		ino_t ino, \
17751565Smckusick 		struct vnode **vpp))) dead_badop)
17851565Smckusick #define dead_valloc ((int (*) __P(( \
17951565Smckusick 		struct vnode *pvp, \
18051565Smckusick 		int mode, \
18151565Smckusick 		struct ucred *cred, \
18251565Smckusick 		struct vnode **vpp))) dead_badop)
18351565Smckusick #define dead_vfree ((void (*) __P(( \
18451565Smckusick 		struct vnode *pvp, \
18551565Smckusick 		ino_t ino, \
18651565Smckusick 		int mode))) dead_badop)
18751565Smckusick #define dead_truncate ((int (*) __P(( \
18851565Smckusick 		struct vnode *vp, \
18951565Smckusick 		u_long length, \
19051565Smckusick 		int flags))) nullop)
19151565Smckusick #define dead_update ((int (*) __P(( \
19251565Smckusick 		struct vnode *vp, \
19351565Smckusick 		struct timeval *ta, \
19451565Smckusick 		struct timeval *tm, \
19551565Smckusick 		int waitfor))) nullop)
19651565Smckusick #define dead_bwrite ((int (*) __P(( \
19751565Smckusick 		struct buf *bp))) nullop)
19839483Smckusick 
19939483Smckusick struct vnodeops dead_vnodeops = {
20039483Smckusick 	dead_lookup,	/* lookup */
20148012Smckusick 	dead_create,	/* create */
20248012Smckusick 	dead_mknod,	/* mknod */
20339483Smckusick 	dead_open,	/* open */
20448012Smckusick 	dead_close,	/* close */
20548012Smckusick 	dead_access,	/* access */
20648012Smckusick 	dead_getattr,	/* getattr */
20748012Smckusick 	dead_setattr,	/* setattr */
20839483Smckusick 	dead_read,	/* read */
20939483Smckusick 	dead_write,	/* write */
21039483Smckusick 	dead_ioctl,	/* ioctl */
21139483Smckusick 	dead_select,	/* select */
21248012Smckusick 	dead_mmap,	/* mmap */
21348012Smckusick 	dead_fsync,	/* fsync */
21448012Smckusick 	dead_seek,	/* seek */
21548012Smckusick 	dead_remove,	/* remove */
21648012Smckusick 	dead_link,	/* link */
21748012Smckusick 	dead_rename,	/* rename */
21848012Smckusick 	dead_mkdir,	/* mkdir */
21948012Smckusick 	dead_rmdir,	/* rmdir */
22048012Smckusick 	dead_symlink,	/* symlink */
22148012Smckusick 	dead_readdir,	/* readdir */
22248012Smckusick 	dead_readlink,	/* readlink */
22348012Smckusick 	dead_abortop,	/* abortop */
22448012Smckusick 	dead_inactive,	/* inactive */
22548012Smckusick 	dead_reclaim,	/* reclaim */
22639483Smckusick 	dead_lock,	/* lock */
22748012Smckusick 	dead_unlock,	/* unlock */
22839508Smckusick 	dead_bmap,	/* bmap */
22939483Smckusick 	dead_strategy,	/* strategy */
23039911Smckusick 	dead_print,	/* print */
23148012Smckusick 	dead_islocked,	/* islocked */
23248012Smckusick 	dead_advlock,	/* advlock */
23351565Smckusick 	dead_blkatoff,	/* blkatoff */
23451565Smckusick 	dead_vget,	/* vget */
23551565Smckusick 	dead_valloc,	/* valloc */
23651565Smckusick 	dead_vfree,	/* vfree */
23751565Smckusick 	dead_truncate,	/* truncate */
23851565Smckusick 	dead_update,	/* update */
23951565Smckusick 	dead_bwrite,	/* bwrite */
24039483Smckusick };
24139483Smckusick 
24239483Smckusick /*
24339483Smckusick  * Trivial lookup routine that always fails.
24439483Smckusick  */
24548012Smckusick /* ARGSUSED */
246*52303Sheideman int
247*52303Sheideman dead_lookup(dvp, vpp, cnp)
248*52303Sheideman 	struct vnode *dvp;
249*52303Sheideman 	struct vnode **vpp;
250*52303Sheideman 	struct componentname *cnp;
25139483Smckusick {
25239483Smckusick 
253*52303Sheideman 	*vpp = NULL;
25439483Smckusick 	return (ENOTDIR);
25539483Smckusick }
25639483Smckusick 
25739483Smckusick /*
25839483Smckusick  * Open always fails as if device did not exist.
25939483Smckusick  */
26039483Smckusick /* ARGSUSED */
26148012Smckusick dead_open(vp, mode, cred, p)
26239483Smckusick 	struct vnode *vp;
26339483Smckusick 	int mode;
26439483Smckusick 	struct ucred *cred;
26548012Smckusick 	struct proc *p;
26639483Smckusick {
26739483Smckusick 
26839483Smckusick 	return (ENXIO);
26939483Smckusick }
27039483Smckusick 
27139483Smckusick /*
27239483Smckusick  * Vnode op for read
27339483Smckusick  */
27439591Smckusick /* ARGSUSED */
27539591Smckusick dead_read(vp, uio, ioflag, cred)
27639483Smckusick 	struct vnode *vp;
27739483Smckusick 	struct uio *uio;
27839483Smckusick 	int ioflag;
27939483Smckusick 	struct ucred *cred;
28039483Smckusick {
28139483Smckusick 
28239591Smckusick 	if (chkvnlock(vp))
28339591Smckusick 		panic("dead_read: lock");
28439591Smckusick 	/*
28539591Smckusick 	 * Return EOF for character devices, EIO for others
28639591Smckusick 	 */
28739591Smckusick 	if (vp->v_type != VCHR)
28839483Smckusick 		return (EIO);
28939591Smckusick 	return (0);
29039483Smckusick }
29139483Smckusick 
29239483Smckusick /*
29339483Smckusick  * Vnode op for write
29439483Smckusick  */
29539591Smckusick /* ARGSUSED */
29639591Smckusick dead_write(vp, uio, ioflag, cred)
29739483Smckusick 	register struct vnode *vp;
29839483Smckusick 	struct uio *uio;
29939483Smckusick 	int ioflag;
30039483Smckusick 	struct ucred *cred;
30139483Smckusick {
30239483Smckusick 
30339591Smckusick 	if (chkvnlock(vp))
30439591Smckusick 		panic("dead_write: lock");
30539591Smckusick 	return (EIO);
30639483Smckusick }
30739483Smckusick 
30839483Smckusick /*
30939483Smckusick  * Device ioctl operation.
31039483Smckusick  */
31139483Smckusick /* ARGSUSED */
31248012Smckusick dead_ioctl(vp, com, data, fflag, cred, p)
31339483Smckusick 	struct vnode *vp;
31439483Smckusick 	register int com;
31539483Smckusick 	caddr_t data;
31639483Smckusick 	int fflag;
31739483Smckusick 	struct ucred *cred;
31848012Smckusick 	struct proc *p;
31939483Smckusick {
32039483Smckusick 
32139519Smckusick 	if (!chkvnlock(vp))
32239483Smckusick 		return (EBADF);
32348012Smckusick 	return (VOP_IOCTL(vp, com, data, fflag, cred, p));
32439483Smckusick }
32539483Smckusick 
32639483Smckusick /* ARGSUSED */
32748012Smckusick dead_select(vp, which, fflags, cred, p)
32839483Smckusick 	struct vnode *vp;
32940188Smckusick 	int which, fflags;
33039483Smckusick 	struct ucred *cred;
33148012Smckusick 	struct proc *p;
33239483Smckusick {
33339483Smckusick 
33439483Smckusick 	/*
33539483Smckusick 	 * Let the user find out that the descriptor is gone.
33639483Smckusick 	 */
33739483Smckusick 	return (1);
33839483Smckusick }
33939483Smckusick 
34039483Smckusick /*
34139483Smckusick  * Just call the device strategy routine
34239483Smckusick  */
34339483Smckusick dead_strategy(bp)
34439483Smckusick 	register struct buf *bp;
34539483Smckusick {
34639483Smckusick 
34739519Smckusick 	if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) {
34839518Smckusick 		bp->b_flags |= B_ERROR;
34939853Smckusick 		biodone(bp);
35039483Smckusick 		return (EIO);
35139518Smckusick 	}
35239483Smckusick 	return (VOP_STRATEGY(bp));
35339483Smckusick }
35439483Smckusick 
35539483Smckusick /*
35639483Smckusick  * Wait until the vnode has finished changing state.
35739483Smckusick  */
35839483Smckusick dead_lock(vp)
35939483Smckusick 	struct vnode *vp;
36039483Smckusick {
36139483Smckusick 
36239519Smckusick 	if (!chkvnlock(vp))
36339483Smckusick 		return (0);
36439483Smckusick 	return (VOP_LOCK(vp));
36539483Smckusick }
36639483Smckusick 
36739483Smckusick /*
36839508Smckusick  * Wait until the vnode has finished changing state.
36939508Smckusick  */
37039508Smckusick dead_bmap(vp, bn, vpp, bnp)
37139508Smckusick 	struct vnode *vp;
37239508Smckusick 	daddr_t bn;
37339508Smckusick 	struct vnode **vpp;
37439508Smckusick 	daddr_t *bnp;
37539508Smckusick {
37639508Smckusick 
37739519Smckusick 	if (!chkvnlock(vp))
37839508Smckusick 		return (EIO);
37939508Smckusick 	return (VOP_BMAP(vp, bn, vpp, bnp));
38039508Smckusick }
38139508Smckusick 
38239508Smckusick /*
38339911Smckusick  * Print out the contents of a dead vnode.
38439911Smckusick  */
38545110Smckusick /* ARGSUSED */
38639911Smckusick dead_print(vp)
38739911Smckusick 	struct vnode *vp;
38839911Smckusick {
38939911Smckusick 
39039911Smckusick 	printf("tag VT_NON, dead vnode\n");
39139911Smckusick }
39239911Smckusick 
39339911Smckusick /*
39439486Smckusick  * Empty vnode failed operation
39539486Smckusick  */
39639486Smckusick dead_ebadf()
39739486Smckusick {
39839486Smckusick 
39939486Smckusick 	return (EBADF);
40039486Smckusick }
40139486Smckusick 
40239486Smckusick /*
40339483Smckusick  * Empty vnode bad operation
40439483Smckusick  */
40539483Smckusick dead_badop()
40639483Smckusick {
40739483Smckusick 
40839483Smckusick 	panic("dead_badop called");
40939483Smckusick 	/* NOTREACHED */
41039483Smckusick }
41139483Smckusick 
41239483Smckusick /*
41339483Smckusick  * Empty vnode null operation
41439483Smckusick  */
41539483Smckusick dead_nullop()
41639483Smckusick {
41739483Smckusick 
41839483Smckusick 	return (0);
41939483Smckusick }
42039519Smckusick 
42139519Smckusick /*
42239519Smckusick  * We have to wait during times when the vnode is
42339519Smckusick  * in a state of change.
42439519Smckusick  */
42539519Smckusick chkvnlock(vp)
42639519Smckusick 	register struct vnode *vp;
42739519Smckusick {
42839519Smckusick 	int locked = 0;
42939519Smckusick 
43039519Smckusick 	while (vp->v_flag & VXLOCK) {
43139519Smckusick 		vp->v_flag |= VXWANT;
43239519Smckusick 		sleep((caddr_t)vp, PINOD);
43339519Smckusick 		locked = 1;
43439519Smckusick 	}
43539519Smckusick 	return (locked);
43639519Smckusick }
437