xref: /csrg-svn/sys/miscfs/deadfs/dead_vnops.c (revision 48012)
139483Smckusick /*
239483Smckusick  * Copyright (c) 1989 The Regents of the University of California.
339483Smckusick  * All rights reserved.
439483Smckusick  *
544429Sbostic  * %sccs.include.redist.c%
639483Smckusick  *
7*48012Smckusick  *	@(#)dead_vnops.c	7.13 (Berkeley) 04/15/91
839483Smckusick  */
939483Smckusick 
1039483Smckusick #include "param.h"
11*48012Smckusick #include "systm.h"
1239483Smckusick #include "time.h"
1339483Smckusick #include "vnode.h"
1439483Smckusick #include "errno.h"
1539483Smckusick #include "namei.h"
1639483Smckusick #include "buf.h"
1739483Smckusick 
18*48012Smckusick /*
19*48012Smckusick  * Prototypes for dead operations on vnodes.
20*48012Smckusick  */
21*48012Smckusick int	dead_badop(),
22*48012Smckusick 	dead_ebadf();
23*48012Smckusick int	dead_lookup __P((
24*48012Smckusick 		struct vnode *vp,
25*48012Smckusick 		struct nameidata *ndp,
26*48012Smckusick 		struct proc *p));
27*48012Smckusick #define dead_create ((int (*) __P(( \
28*48012Smckusick 		struct nameidata *ndp, \
29*48012Smckusick 		struct vattr *vap, \
30*48012Smckusick 		struct proc *p))) dead_badop)
31*48012Smckusick #define dead_mknod ((int (*) __P(( \
32*48012Smckusick 		struct nameidata *ndp, \
33*48012Smckusick 		struct vattr *vap, \
34*48012Smckusick 		struct ucred *cred, \
35*48012Smckusick 		struct proc *p))) dead_badop)
36*48012Smckusick int	dead_open __P((
37*48012Smckusick 		struct vnode *vp,
38*48012Smckusick 		int mode,
39*48012Smckusick 		struct ucred *cred,
40*48012Smckusick 		struct proc *p));
41*48012Smckusick #define dead_close ((int (*) __P(( \
42*48012Smckusick 		struct vnode *vp, \
43*48012Smckusick 		int fflag, \
44*48012Smckusick 		struct ucred *cred, \
45*48012Smckusick 		struct proc *p))) nullop)
46*48012Smckusick #define dead_access ((int (*) __P(( \
47*48012Smckusick 		struct vnode *vp, \
48*48012Smckusick 		int mode, \
49*48012Smckusick 		struct ucred *cred, \
50*48012Smckusick 		struct proc *p))) dead_ebadf)
51*48012Smckusick #define dead_getattr ((int (*) __P(( \
52*48012Smckusick 		struct vnode *vp, \
53*48012Smckusick 		struct vattr *vap, \
54*48012Smckusick 		struct ucred *cred, \
55*48012Smckusick 		struct proc *p))) dead_ebadf)
56*48012Smckusick #define dead_setattr ((int (*) __P(( \
57*48012Smckusick 		struct vnode *vp, \
58*48012Smckusick 		struct vattr *vap, \
59*48012Smckusick 		struct ucred *cred, \
60*48012Smckusick 		struct proc *p))) dead_ebadf)
61*48012Smckusick int	dead_read __P((
62*48012Smckusick 		struct vnode *vp,
63*48012Smckusick 		struct uio *uio,
64*48012Smckusick 		int ioflag,
65*48012Smckusick 		struct ucred *cred));
66*48012Smckusick int	dead_write __P((
67*48012Smckusick 		struct vnode *vp,
68*48012Smckusick 		struct uio *uio,
69*48012Smckusick 		int ioflag,
70*48012Smckusick 		struct ucred *cred));
71*48012Smckusick int	dead_ioctl __P((
72*48012Smckusick 		struct vnode *vp,
73*48012Smckusick 		int command,
74*48012Smckusick 		caddr_t data,
75*48012Smckusick 		int fflag,
76*48012Smckusick 		struct ucred *cred,
77*48012Smckusick 		struct proc *p));
78*48012Smckusick int	dead_select __P((
79*48012Smckusick 		struct vnode *vp,
80*48012Smckusick 		int which,
81*48012Smckusick 		int fflags,
82*48012Smckusick 		struct ucred *cred,
83*48012Smckusick 		struct proc *p));
84*48012Smckusick #define dead_mmap ((int (*) __P(( \
85*48012Smckusick 		struct vnode *vp, \
86*48012Smckusick 		int fflags, \
87*48012Smckusick 		struct ucred *cred, \
88*48012Smckusick 		struct proc *p))) dead_badop)
89*48012Smckusick #define dead_fsync ((int (*) __P(( \
90*48012Smckusick 		struct vnode *vp, \
91*48012Smckusick 		int fflags, \
92*48012Smckusick 		struct ucred *cred, \
93*48012Smckusick 		int waitfor, \
94*48012Smckusick 		struct proc *p))) nullop)
95*48012Smckusick #define dead_seek ((int (*) __P(( \
96*48012Smckusick 		struct vnode *vp, \
97*48012Smckusick 		off_t oldoff, \
98*48012Smckusick 		off_t newoff, \
99*48012Smckusick 		struct ucred *cred))) nullop)
100*48012Smckusick #define dead_remove ((int (*) __P(( \
101*48012Smckusick 		struct nameidata *ndp, \
102*48012Smckusick 		struct proc *p))) dead_badop)
103*48012Smckusick #define dead_link ((int (*) __P(( \
104*48012Smckusick 		struct vnode *vp, \
105*48012Smckusick 		struct nameidata *ndp, \
106*48012Smckusick 		struct proc *p))) dead_badop)
107*48012Smckusick #define dead_rename ((int (*) __P(( \
108*48012Smckusick 		struct nameidata *fndp, \
109*48012Smckusick 		struct nameidata *tdnp, \
110*48012Smckusick 		struct proc *p))) dead_badop)
111*48012Smckusick #define dead_mkdir ((int (*) __P(( \
112*48012Smckusick 		struct nameidata *ndp, \
113*48012Smckusick 		struct vattr *vap, \
114*48012Smckusick 		struct proc *p))) dead_badop)
115*48012Smckusick #define dead_rmdir ((int (*) __P(( \
116*48012Smckusick 		struct nameidata *ndp, \
117*48012Smckusick 		struct proc *p))) dead_badop)
118*48012Smckusick #define dead_symlink ((int (*) __P(( \
119*48012Smckusick 		struct nameidata *ndp, \
120*48012Smckusick 		struct vattr *vap, \
121*48012Smckusick 		char *target, \
122*48012Smckusick 		struct proc *p))) dead_badop)
123*48012Smckusick #define dead_readdir ((int (*) __P(( \
124*48012Smckusick 		struct vnode *vp, \
125*48012Smckusick 		struct uio *uio, \
126*48012Smckusick 		struct ucred *cred, \
127*48012Smckusick 		int *eofflagp))) dead_ebadf)
128*48012Smckusick #define dead_readlink ((int (*) __P(( \
129*48012Smckusick 		struct vnode *vp, \
130*48012Smckusick 		struct uio *uio, \
131*48012Smckusick 		struct ucred *cred))) dead_ebadf)
132*48012Smckusick #define dead_abortop ((int (*) __P(( \
133*48012Smckusick 		struct nameidata *ndp))) dead_badop)
134*48012Smckusick #define dead_inactive ((int (*) __P(( \
135*48012Smckusick 		struct vnode *vp, \
136*48012Smckusick 		struct proc *p))) nullop)
137*48012Smckusick #define dead_reclaim ((int (*) __P(( \
138*48012Smckusick 		struct vnode *vp))) nullop)
139*48012Smckusick int	dead_lock __P((
140*48012Smckusick 		struct vnode *vp));
141*48012Smckusick #define dead_unlock ((int (*) __P(( \
142*48012Smckusick 		struct vnode *vp))) nullop)
143*48012Smckusick int	dead_bmap __P((
144*48012Smckusick 		struct vnode *vp,
145*48012Smckusick 		daddr_t bn,
146*48012Smckusick 		struct vnode **vpp,
147*48012Smckusick 		daddr_t *bnp));
148*48012Smckusick int	dead_strategy __P((
149*48012Smckusick 		struct buf *bp));
150*48012Smckusick int	dead_print __P((
151*48012Smckusick 		struct vnode *vp));
152*48012Smckusick #define dead_islocked ((int (*) __P(( \
153*48012Smckusick 		struct vnode *vp))) nullop)
154*48012Smckusick #define dead_advlock ((int (*) __P(( \
155*48012Smckusick 		struct vnode *vp, \
156*48012Smckusick 		caddr_t id, \
157*48012Smckusick 		int op, \
158*48012Smckusick 		struct flock *fl, \
159*48012Smckusick 		int flags))) dead_ebadf)
16039483Smckusick 
16139483Smckusick struct vnodeops dead_vnodeops = {
16239483Smckusick 	dead_lookup,	/* lookup */
163*48012Smckusick 	dead_create,	/* create */
164*48012Smckusick 	dead_mknod,	/* mknod */
16539483Smckusick 	dead_open,	/* open */
166*48012Smckusick 	dead_close,	/* close */
167*48012Smckusick 	dead_access,	/* access */
168*48012Smckusick 	dead_getattr,	/* getattr */
169*48012Smckusick 	dead_setattr,	/* setattr */
17039483Smckusick 	dead_read,	/* read */
17139483Smckusick 	dead_write,	/* write */
17239483Smckusick 	dead_ioctl,	/* ioctl */
17339483Smckusick 	dead_select,	/* select */
174*48012Smckusick 	dead_mmap,	/* mmap */
175*48012Smckusick 	dead_fsync,	/* fsync */
176*48012Smckusick 	dead_seek,	/* seek */
177*48012Smckusick 	dead_remove,	/* remove */
178*48012Smckusick 	dead_link,	/* link */
179*48012Smckusick 	dead_rename,	/* rename */
180*48012Smckusick 	dead_mkdir,	/* mkdir */
181*48012Smckusick 	dead_rmdir,	/* rmdir */
182*48012Smckusick 	dead_symlink,	/* symlink */
183*48012Smckusick 	dead_readdir,	/* readdir */
184*48012Smckusick 	dead_readlink,	/* readlink */
185*48012Smckusick 	dead_abortop,	/* abortop */
186*48012Smckusick 	dead_inactive,	/* inactive */
187*48012Smckusick 	dead_reclaim,	/* reclaim */
18839483Smckusick 	dead_lock,	/* lock */
189*48012Smckusick 	dead_unlock,	/* unlock */
19039508Smckusick 	dead_bmap,	/* bmap */
19139483Smckusick 	dead_strategy,	/* strategy */
19239911Smckusick 	dead_print,	/* print */
193*48012Smckusick 	dead_islocked,	/* islocked */
194*48012Smckusick 	dead_advlock,	/* advlock */
19539483Smckusick };
19639483Smckusick 
19739483Smckusick /*
19839483Smckusick  * Trivial lookup routine that always fails.
19939483Smckusick  */
200*48012Smckusick /* ARGSUSED */
201*48012Smckusick dead_lookup(vp, ndp, p)
20239483Smckusick 	struct vnode *vp;
20339483Smckusick 	struct nameidata *ndp;
204*48012Smckusick 	struct proc *p;
20539483Smckusick {
20639483Smckusick 
20739483Smckusick 	ndp->ni_dvp = vp;
20839483Smckusick 	ndp->ni_vp = NULL;
20939483Smckusick 	return (ENOTDIR);
21039483Smckusick }
21139483Smckusick 
21239483Smckusick /*
21339483Smckusick  * Open always fails as if device did not exist.
21439483Smckusick  */
21539483Smckusick /* ARGSUSED */
216*48012Smckusick dead_open(vp, mode, cred, p)
21739483Smckusick 	struct vnode *vp;
21839483Smckusick 	int mode;
21939483Smckusick 	struct ucred *cred;
220*48012Smckusick 	struct proc *p;
22139483Smckusick {
22239483Smckusick 
22339483Smckusick 	return (ENXIO);
22439483Smckusick }
22539483Smckusick 
22639483Smckusick /*
22739483Smckusick  * Vnode op for read
22839483Smckusick  */
22939591Smckusick /* ARGSUSED */
23039591Smckusick dead_read(vp, uio, ioflag, cred)
23139483Smckusick 	struct vnode *vp;
23239483Smckusick 	struct uio *uio;
23339483Smckusick 	int ioflag;
23439483Smckusick 	struct ucred *cred;
23539483Smckusick {
23639483Smckusick 
23739591Smckusick 	if (chkvnlock(vp))
23839591Smckusick 		panic("dead_read: lock");
23939591Smckusick 	/*
24039591Smckusick 	 * Return EOF for character devices, EIO for others
24139591Smckusick 	 */
24239591Smckusick 	if (vp->v_type != VCHR)
24339483Smckusick 		return (EIO);
24439591Smckusick 	return (0);
24539483Smckusick }
24639483Smckusick 
24739483Smckusick /*
24839483Smckusick  * Vnode op for write
24939483Smckusick  */
25039591Smckusick /* ARGSUSED */
25139591Smckusick dead_write(vp, uio, ioflag, cred)
25239483Smckusick 	register struct vnode *vp;
25339483Smckusick 	struct uio *uio;
25439483Smckusick 	int ioflag;
25539483Smckusick 	struct ucred *cred;
25639483Smckusick {
25739483Smckusick 
25839591Smckusick 	if (chkvnlock(vp))
25939591Smckusick 		panic("dead_write: lock");
26039591Smckusick 	return (EIO);
26139483Smckusick }
26239483Smckusick 
26339483Smckusick /*
26439483Smckusick  * Device ioctl operation.
26539483Smckusick  */
26639483Smckusick /* ARGSUSED */
267*48012Smckusick dead_ioctl(vp, com, data, fflag, cred, p)
26839483Smckusick 	struct vnode *vp;
26939483Smckusick 	register int com;
27039483Smckusick 	caddr_t data;
27139483Smckusick 	int fflag;
27239483Smckusick 	struct ucred *cred;
273*48012Smckusick 	struct proc *p;
27439483Smckusick {
27539483Smckusick 
27639519Smckusick 	if (!chkvnlock(vp))
27739483Smckusick 		return (EBADF);
278*48012Smckusick 	return (VOP_IOCTL(vp, com, data, fflag, cred, p));
27939483Smckusick }
28039483Smckusick 
28139483Smckusick /* ARGSUSED */
282*48012Smckusick dead_select(vp, which, fflags, cred, p)
28339483Smckusick 	struct vnode *vp;
28440188Smckusick 	int which, fflags;
28539483Smckusick 	struct ucred *cred;
286*48012Smckusick 	struct proc *p;
28739483Smckusick {
28839483Smckusick 
28939483Smckusick 	/*
29039483Smckusick 	 * Let the user find out that the descriptor is gone.
29139483Smckusick 	 */
29239483Smckusick 	return (1);
29339483Smckusick }
29439483Smckusick 
29539483Smckusick /*
29639483Smckusick  * Just call the device strategy routine
29739483Smckusick  */
29839483Smckusick dead_strategy(bp)
29939483Smckusick 	register struct buf *bp;
30039483Smckusick {
30139483Smckusick 
30239519Smckusick 	if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) {
30339518Smckusick 		bp->b_flags |= B_ERROR;
30439853Smckusick 		biodone(bp);
30539483Smckusick 		return (EIO);
30639518Smckusick 	}
30739483Smckusick 	return (VOP_STRATEGY(bp));
30839483Smckusick }
30939483Smckusick 
31039483Smckusick /*
31139483Smckusick  * Wait until the vnode has finished changing state.
31239483Smckusick  */
31339483Smckusick dead_lock(vp)
31439483Smckusick 	struct vnode *vp;
31539483Smckusick {
31639483Smckusick 
31739519Smckusick 	if (!chkvnlock(vp))
31839483Smckusick 		return (0);
31939483Smckusick 	return (VOP_LOCK(vp));
32039483Smckusick }
32139483Smckusick 
32239483Smckusick /*
32339508Smckusick  * Wait until the vnode has finished changing state.
32439508Smckusick  */
32539508Smckusick dead_bmap(vp, bn, vpp, bnp)
32639508Smckusick 	struct vnode *vp;
32739508Smckusick 	daddr_t bn;
32839508Smckusick 	struct vnode **vpp;
32939508Smckusick 	daddr_t *bnp;
33039508Smckusick {
33139508Smckusick 
33239519Smckusick 	if (!chkvnlock(vp))
33339508Smckusick 		return (EIO);
33439508Smckusick 	return (VOP_BMAP(vp, bn, vpp, bnp));
33539508Smckusick }
33639508Smckusick 
33739508Smckusick /*
33839911Smckusick  * Print out the contents of a dead vnode.
33939911Smckusick  */
34045110Smckusick /* ARGSUSED */
34139911Smckusick dead_print(vp)
34239911Smckusick 	struct vnode *vp;
34339911Smckusick {
34439911Smckusick 
34539911Smckusick 	printf("tag VT_NON, dead vnode\n");
34639911Smckusick }
34739911Smckusick 
34839911Smckusick /*
34939486Smckusick  * Empty vnode failed operation
35039486Smckusick  */
35139486Smckusick dead_ebadf()
35239486Smckusick {
35339486Smckusick 
35439486Smckusick 	return (EBADF);
35539486Smckusick }
35639486Smckusick 
35739486Smckusick /*
35839483Smckusick  * Empty vnode bad operation
35939483Smckusick  */
36039483Smckusick dead_badop()
36139483Smckusick {
36239483Smckusick 
36339483Smckusick 	panic("dead_badop called");
36439483Smckusick 	/* NOTREACHED */
36539483Smckusick }
36639483Smckusick 
36739483Smckusick /*
36839483Smckusick  * Empty vnode null operation
36939483Smckusick  */
37039483Smckusick dead_nullop()
37139483Smckusick {
37239483Smckusick 
37339483Smckusick 	return (0);
37439483Smckusick }
37539519Smckusick 
37639519Smckusick /*
37739519Smckusick  * We have to wait during times when the vnode is
37839519Smckusick  * in a state of change.
37939519Smckusick  */
38039519Smckusick chkvnlock(vp)
38139519Smckusick 	register struct vnode *vp;
38239519Smckusick {
38339519Smckusick 	int locked = 0;
38439519Smckusick 
38539519Smckusick 	while (vp->v_flag & VXLOCK) {
38639519Smckusick 		vp->v_flag |= VXWANT;
38739519Smckusick 		sleep((caddr_t)vp, PINOD);
38839519Smckusick 		locked = 1;
38939519Smckusick 	}
39039519Smckusick 	return (locked);
39139519Smckusick }
392