1 /* $OpenBSD: vfs_default.c,v 1.26 2005/07/03 20:13:59 drahn Exp $ */
2
3 /*
4 * Portions of this code are:
5 *
6 * Copyright (c) 1989, 1993
7 * The Regents of the University of California. All rights reserved.
8 * (c) UNIX System Laboratories, Inc.
9 * All or some portions of this file are derived from material licensed
10 * to the University of California by American Telephone and Telegraph
11 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
12 * the permission of UNIX System Laboratories, Inc.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/proc.h>
43 #include <sys/mount.h>
44 #include <sys/vnode.h>
45 #include <sys/namei.h>
46 #include <sys/malloc.h>
47 #include <sys/pool.h>
48 #include <sys/event.h>
49 #include <miscfs/specfs/specdev.h>
50
51
52 extern struct simplelock spechash_slock;
53
54 int filt_generic_readwrite(struct knote *kn, long hint);
55 void filt_generic_detach(struct knote *kn);
56
57 /*
58 * Eliminate all activity associated with the requested vnode
59 * and with all vnodes aliased to the requested vnode.
60 */
61 int
vop_generic_revoke(v)62 vop_generic_revoke(v)
63 void *v;
64 {
65 struct vop_revoke_args /* {
66 struct vnodeop_desc *a_desc;
67 struct vnode *a_vp;
68 int a_flags;
69 } */ *ap = v;
70 struct vnode *vp, *vq;
71 struct proc *p = curproc;
72
73 #ifdef DIAGNOSTIC
74 if ((ap->a_flags & REVOKEALL) == 0)
75 panic("vop_generic_revoke");
76 #endif
77
78 vp = ap->a_vp;
79 simple_lock(&vp->v_interlock);
80
81 if (vp->v_flag & VALIASED) {
82 /*
83 * If a vgone (or vclean) is already in progress,
84 * wait until it is done and return.
85 */
86 if (vp->v_flag & VXLOCK) {
87 vp->v_flag |= VXWANT;
88 simple_unlock(&vp->v_interlock);
89 tsleep(vp, PINOD, "vop_generic_revokeall", 0);
90 return(0);
91 }
92 /*
93 * Ensure that vp will not be vgone'd while we
94 * are eliminating its aliases.
95 */
96 vp->v_flag |= VXLOCK;
97 simple_unlock(&vp->v_interlock);
98 while (vp->v_flag & VALIASED) {
99 simple_lock(&spechash_slock);
100 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
101 if (vq->v_rdev != vp->v_rdev ||
102 vq->v_type != vp->v_type || vp == vq)
103 continue;
104 simple_unlock(&spechash_slock);
105 vgone(vq);
106 break;
107 }
108 simple_unlock(&spechash_slock);
109 }
110 /*
111 * Remove the lock so that vgone below will
112 * really eliminate the vnode after which time
113 * vgone will awaken any sleepers.
114 */
115 simple_lock(&vp->v_interlock);
116 vp->v_flag &= ~VXLOCK;
117 }
118 vgonel(vp, p);
119 return (0);
120 }
121
122
123 int
vop_generic_bwrite(v)124 vop_generic_bwrite(v)
125 void *v;
126 {
127 struct vop_bwrite_args *ap = v;
128
129 return (bwrite(ap->a_bp));
130 }
131
132
133 int
vop_generic_abortop(v)134 vop_generic_abortop(v)
135 void *v;
136 {
137 struct vop_abortop_args /* {
138 struct vnodeop_desc *a_desc;
139 struct vnode *a_dvp;
140 struct componentname *a_cnp;
141 } */ *ap = v;
142
143 if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
144 pool_put(&namei_pool, ap->a_cnp->cn_pnbuf);
145 return (0);
146 }
147
148 /*
149 * Stubs to use when there is no locking to be done on the underlying object.
150 * A minimal shared lock is necessary to ensure that the underlying object
151 * is not revoked while an operation is in progress. So, an active shared
152 * count is maintained in an auxiliary vnode lock structure.
153 */
154 int
vop_generic_lock(v)155 vop_generic_lock(v)
156 void *v;
157 {
158 struct vop_lock_args /* {
159 struct vnodeop_desc *a_desc;
160 struct vnode *a_vp;
161 int a_flags;
162 struct proc *a_p;
163 } */ *ap = v;
164
165 #ifdef notyet
166 /*
167 * This code cannot be used until all the non-locking filesystems
168 * (notably NFS) are converted to properly lock and release nodes.
169 * Also, certain vnode operations change the locking state within
170 * the operation (create, mknod, remove, link, rename, mkdir, rmdir,
171 * and symlink). Ideally these operations should not change the
172 * lock state, but should be changed to let the caller of the
173 * function unlock them. Otherwise all intermediate vnode layers
174 * (such as union, umapfs, etc) must catch these functions to do
175 * the necessary locking at their layer. Note that the inactive
176 * and lookup operations also change their lock state, but this
177 * cannot be avoided, so these two operations will always need
178 * to be handled in intermediate layers.
179 */
180 struct vnode *vp = ap->a_vp;
181 int vnflags, flags = ap->a_flags;
182
183 if (vp->v_vnlock == NULL) {
184 if ((flags & LK_TYPE_MASK) == LK_DRAIN)
185 return (0);
186 MALLOC(vp->v_vnlock, struct lock *, sizeof(struct lock),
187 M_VNODE, M_WAITOK);
188 lockinit(vp->v_vnlock, PVFS, "vnlock", 0, 0);
189 }
190 switch (flags & LK_TYPE_MASK) {
191 case LK_DRAIN:
192 vnflags = LK_DRAIN;
193 break;
194 case LK_EXCLUSIVE:
195 case LK_SHARED:
196 vnflags = LK_SHARED;
197 break;
198 case LK_UPGRADE:
199 case LK_EXCLUPGRADE:
200 case LK_DOWNGRADE:
201 return (0);
202 case LK_RELEASE:
203 default:
204 panic("vop_generic_lock: bad operation %d", flags & LK_TYPE_MASK);
205 }
206 if (flags & LK_INTERLOCK)
207 vnflags |= LK_INTERLOCK;
208 return(lockmgr(vp->v_vnlock, vnflags, &vp->v_interlock, ap->a_p));
209 #else /* for now */
210 /*
211 * Since we are not using the lock manager, we must clear
212 * the interlock here.
213 */
214 if (ap->a_flags & LK_INTERLOCK)
215 simple_unlock(&ap->a_vp->v_interlock);
216 return (0);
217 #endif
218 }
219
220 /*
221 * Decrement the active use count.
222 */
223
224 int
vop_generic_unlock(v)225 vop_generic_unlock(v)
226 void *v;
227 {
228 return (0);
229 }
230
231 /*
232 * Return whether or not the node is in use.
233 */
234 int
vop_generic_islocked(v)235 vop_generic_islocked(v)
236 void *v;
237 {
238 return (0);
239 }
240
241 struct filterops generic_filtops =
242 { 1, NULL, filt_generic_detach, filt_generic_readwrite };
243
244 int
vop_generic_kqfilter(v)245 vop_generic_kqfilter(v)
246 void *v;
247 {
248 struct vop_kqfilter_args /* {
249 struct vnodeop_desc *a_desc;
250 struct vnode *a_vp;
251 struct knote *a_kn;
252 } */ *ap = v;
253 struct knote *kn = ap->a_kn;
254
255 switch (kn->kn_filter) {
256 case EVFILT_READ:
257 case EVFILT_WRITE:
258 kn->kn_fop = &generic_filtops;
259 break;
260 default:
261 return (1);
262 }
263
264 return (0);
265 }
266
267 void
filt_generic_detach(struct knote * kn)268 filt_generic_detach(struct knote *kn)
269 {
270 }
271
272 int
filt_generic_readwrite(struct knote * kn,long hint)273 filt_generic_readwrite(struct knote *kn, long hint)
274 {
275 /*
276 * filesystem is gone, so set the EOF flag and schedule
277 * the knote for deletion.
278 */
279 if (hint == NOTE_REVOKE) {
280 kn->kn_flags |= (EV_EOF | EV_ONESHOT);
281 return (1);
282 }
283
284 kn->kn_data = 0;
285 return (1);
286 }
287
288 int lease_check(void *);
289
290 int
lease_check(void * v)291 lease_check(void *v)
292 {
293 return (0);
294 }
295