xref: /original-bsd/sys/miscfs/deadfs/dead_vnops.c (revision 9d1db70c)
1 /*
2  * Copyright (c) 1989 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)dead_vnops.c	7.12 (Berkeley) 02/01/91
8  */
9 
10 #include "param.h"
11 #include "time.h"
12 #include "vnode.h"
13 #include "errno.h"
14 #include "namei.h"
15 #include "buf.h"
16 
17 int	dead_lookup(),
18 	dead_open(),
19 	dead_read(),
20 	dead_write(),
21 	dead_strategy(),
22 	dead_ioctl(),
23 	dead_select(),
24 	dead_lock(),
25 	dead_bmap(),
26 	dead_print(),
27 	dead_ebadf(),
28 	dead_badop(),
29 	dead_nullop();
30 
31 struct vnodeops dead_vnodeops = {
32 	dead_lookup,	/* lookup */
33 	dead_badop,	/* create */
34 	dead_badop,	/* mknod */
35 	dead_open,	/* open */
36 	dead_nullop,	/* close */
37 	dead_ebadf,	/* access */
38 	dead_ebadf,	/* getattr */
39 	dead_ebadf,	/* setattr */
40 	dead_read,	/* read */
41 	dead_write,	/* write */
42 	dead_ioctl,	/* ioctl */
43 	dead_select,	/* select */
44 	dead_badop,	/* mmap */
45 	dead_nullop,	/* fsync */
46 	dead_nullop,	/* seek */
47 	dead_badop,	/* remove */
48 	dead_badop,	/* link */
49 	dead_badop,	/* rename */
50 	dead_badop,	/* mkdir */
51 	dead_badop,	/* rmdir */
52 	dead_badop,	/* symlink */
53 	dead_ebadf,	/* readdir */
54 	dead_ebadf,	/* readlink */
55 	dead_badop,	/* abortop */
56 	dead_nullop,	/* inactive */
57 	dead_nullop,	/* reclaim */
58 	dead_lock,	/* lock */
59 	dead_nullop,	/* unlock */
60 	dead_bmap,	/* bmap */
61 	dead_strategy,	/* strategy */
62 	dead_print,	/* print */
63 	dead_nullop,	/* islocked */
64 	dead_ebadf,	/* advlock */
65 };
66 
67 /*
68  * Trivial lookup routine that always fails.
69  */
70 dead_lookup(vp, ndp)
71 	struct vnode *vp;
72 	struct nameidata *ndp;
73 {
74 
75 	ndp->ni_dvp = vp;
76 	ndp->ni_vp = NULL;
77 	return (ENOTDIR);
78 }
79 
80 /*
81  * Open always fails as if device did not exist.
82  */
83 /* ARGSUSED */
84 dead_open(vp, mode, cred)
85 	struct vnode *vp;
86 	int mode;
87 	struct ucred *cred;
88 {
89 
90 	return (ENXIO);
91 }
92 
93 /*
94  * Vnode op for read
95  */
96 /* ARGSUSED */
97 dead_read(vp, uio, ioflag, cred)
98 	struct vnode *vp;
99 	struct uio *uio;
100 	int ioflag;
101 	struct ucred *cred;
102 {
103 
104 	if (chkvnlock(vp))
105 		panic("dead_read: lock");
106 	/*
107 	 * Return EOF for character devices, EIO for others
108 	 */
109 	if (vp->v_type != VCHR)
110 		return (EIO);
111 	return (0);
112 }
113 
114 /*
115  * Vnode op for write
116  */
117 /* ARGSUSED */
118 dead_write(vp, uio, ioflag, cred)
119 	register struct vnode *vp;
120 	struct uio *uio;
121 	int ioflag;
122 	struct ucred *cred;
123 {
124 
125 	if (chkvnlock(vp))
126 		panic("dead_write: lock");
127 	return (EIO);
128 }
129 
130 /*
131  * Device ioctl operation.
132  */
133 /* ARGSUSED */
134 dead_ioctl(vp, com, data, fflag, cred)
135 	struct vnode *vp;
136 	register int com;
137 	caddr_t data;
138 	int fflag;
139 	struct ucred *cred;
140 {
141 
142 	if (!chkvnlock(vp))
143 		return (EBADF);
144 	return (VOP_IOCTL(vp, com, data, fflag, cred));
145 }
146 
147 /* ARGSUSED */
148 dead_select(vp, which, fflags, cred)
149 	struct vnode *vp;
150 	int which, fflags;
151 	struct ucred *cred;
152 {
153 
154 	/*
155 	 * Let the user find out that the descriptor is gone.
156 	 */
157 	return (1);
158 }
159 
160 /*
161  * Just call the device strategy routine
162  */
163 dead_strategy(bp)
164 	register struct buf *bp;
165 {
166 
167 	if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) {
168 		bp->b_flags |= B_ERROR;
169 		biodone(bp);
170 		return (EIO);
171 	}
172 	return (VOP_STRATEGY(bp));
173 }
174 
175 /*
176  * Wait until the vnode has finished changing state.
177  */
178 dead_lock(vp)
179 	struct vnode *vp;
180 {
181 
182 	if (!chkvnlock(vp))
183 		return (0);
184 	return (VOP_LOCK(vp));
185 }
186 
187 /*
188  * Wait until the vnode has finished changing state.
189  */
190 dead_bmap(vp, bn, vpp, bnp)
191 	struct vnode *vp;
192 	daddr_t bn;
193 	struct vnode **vpp;
194 	daddr_t *bnp;
195 {
196 
197 	if (!chkvnlock(vp))
198 		return (EIO);
199 	return (VOP_BMAP(vp, bn, vpp, bnp));
200 }
201 
202 /*
203  * Print out the contents of a dead vnode.
204  */
205 /* ARGSUSED */
206 dead_print(vp)
207 	struct vnode *vp;
208 {
209 
210 	printf("tag VT_NON, dead vnode\n");
211 }
212 
213 /*
214  * Empty vnode failed operation
215  */
216 dead_ebadf()
217 {
218 
219 	return (EBADF);
220 }
221 
222 /*
223  * Empty vnode bad operation
224  */
225 dead_badop()
226 {
227 
228 	panic("dead_badop called");
229 	/* NOTREACHED */
230 }
231 
232 /*
233  * Empty vnode null operation
234  */
235 dead_nullop()
236 {
237 
238 	return (0);
239 }
240 
241 /*
242  * We have to wait during times when the vnode is
243  * in a state of change.
244  */
245 chkvnlock(vp)
246 	register struct vnode *vp;
247 {
248 	int locked = 0;
249 
250 	while (vp->v_flag & VXLOCK) {
251 		vp->v_flag |= VXWANT;
252 		sleep((caddr_t)vp, PINOD);
253 		locked = 1;
254 	}
255 	return (locked);
256 }
257