xref: /original-bsd/sys/miscfs/deadfs/dead_vnops.c (revision 6ab384a1)
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.11 (Berkeley) 08/24/90
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 };
65 
66 /*
67  * Trivial lookup routine that always fails.
68  */
69 dead_lookup(vp, ndp)
70 	struct vnode *vp;
71 	struct nameidata *ndp;
72 {
73 
74 	ndp->ni_dvp = vp;
75 	ndp->ni_vp = NULL;
76 	return (ENOTDIR);
77 }
78 
79 /*
80  * Open always fails as if device did not exist.
81  */
82 /* ARGSUSED */
83 dead_open(vp, mode, cred)
84 	struct vnode *vp;
85 	int mode;
86 	struct ucred *cred;
87 {
88 
89 	return (ENXIO);
90 }
91 
92 /*
93  * Vnode op for read
94  */
95 /* ARGSUSED */
96 dead_read(vp, uio, ioflag, cred)
97 	struct vnode *vp;
98 	struct uio *uio;
99 	int ioflag;
100 	struct ucred *cred;
101 {
102 
103 	if (chkvnlock(vp))
104 		panic("dead_read: lock");
105 	/*
106 	 * Return EOF for character devices, EIO for others
107 	 */
108 	if (vp->v_type != VCHR)
109 		return (EIO);
110 	return (0);
111 }
112 
113 /*
114  * Vnode op for write
115  */
116 /* ARGSUSED */
117 dead_write(vp, uio, ioflag, cred)
118 	register struct vnode *vp;
119 	struct uio *uio;
120 	int ioflag;
121 	struct ucred *cred;
122 {
123 
124 	if (chkvnlock(vp))
125 		panic("dead_write: lock");
126 	return (EIO);
127 }
128 
129 /*
130  * Device ioctl operation.
131  */
132 /* ARGSUSED */
133 dead_ioctl(vp, com, data, fflag, cred)
134 	struct vnode *vp;
135 	register int com;
136 	caddr_t data;
137 	int fflag;
138 	struct ucred *cred;
139 {
140 
141 	if (!chkvnlock(vp))
142 		return (EBADF);
143 	return (VOP_IOCTL(vp, com, data, fflag, cred));
144 }
145 
146 /* ARGSUSED */
147 dead_select(vp, which, fflags, cred)
148 	struct vnode *vp;
149 	int which, fflags;
150 	struct ucred *cred;
151 {
152 
153 	/*
154 	 * Let the user find out that the descriptor is gone.
155 	 */
156 	return (1);
157 }
158 
159 /*
160  * Just call the device strategy routine
161  */
162 dead_strategy(bp)
163 	register struct buf *bp;
164 {
165 
166 	if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) {
167 		bp->b_flags |= B_ERROR;
168 		biodone(bp);
169 		return (EIO);
170 	}
171 	return (VOP_STRATEGY(bp));
172 }
173 
174 /*
175  * Wait until the vnode has finished changing state.
176  */
177 dead_lock(vp)
178 	struct vnode *vp;
179 {
180 
181 	if (!chkvnlock(vp))
182 		return (0);
183 	return (VOP_LOCK(vp));
184 }
185 
186 /*
187  * Wait until the vnode has finished changing state.
188  */
189 dead_bmap(vp, bn, vpp, bnp)
190 	struct vnode *vp;
191 	daddr_t bn;
192 	struct vnode **vpp;
193 	daddr_t *bnp;
194 {
195 
196 	if (!chkvnlock(vp))
197 		return (EIO);
198 	return (VOP_BMAP(vp, bn, vpp, bnp));
199 }
200 
201 /*
202  * Print out the contents of a dead vnode.
203  */
204 /* ARGSUSED */
205 dead_print(vp)
206 	struct vnode *vp;
207 {
208 
209 	printf("tag VT_NON, dead vnode\n");
210 }
211 
212 /*
213  * Empty vnode failed operation
214  */
215 dead_ebadf()
216 {
217 
218 	return (EBADF);
219 }
220 
221 /*
222  * Empty vnode bad operation
223  */
224 dead_badop()
225 {
226 
227 	panic("dead_badop called");
228 	/* NOTREACHED */
229 }
230 
231 /*
232  * Empty vnode null operation
233  */
234 dead_nullop()
235 {
236 
237 	return (0);
238 }
239 
240 /*
241  * We have to wait during times when the vnode is
242  * in a state of change.
243  */
244 chkvnlock(vp)
245 	register struct vnode *vp;
246 {
247 	int locked = 0;
248 
249 	while (vp->v_flag & VXLOCK) {
250 		vp->v_flag |= VXWANT;
251 		sleep((caddr_t)vp, PINOD);
252 		locked = 1;
253 	}
254 	return (locked);
255 }
256