1 /* $OpenBSD: vfs_default.c,v 1.34 2007/06/01 23:47:56 deraadt 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 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/proc.h>
42 #include <sys/mount.h>
43 #include <sys/vnode.h>
44 #include <sys/namei.h>
45 #include <sys/malloc.h>
46 #include <sys/pool.h>
47 #include <sys/event.h>
48 #include <miscfs/specfs/specdev.h>
49
50 int filt_generic_readwrite(struct knote *, long);
51 void filt_generic_detach(struct knote *);
52
53 /*
54 * Eliminate all activity associated with the requested vnode
55 * and with all vnodes aliased to the requested vnode.
56 */
57 int
58 vop_generic_revoke(void *v)
59 {
60 struct vop_revoke_args *ap = v;
61 struct vnode *vp, *vq;
62 struct proc *p = curproc;
63
64 #ifdef DIAGNOSTIC
65 if ((ap->a_flags & REVOKEALL) == 0)
66 panic("vop_generic_revoke");
67 #endif
68
69 vp = ap->a_vp;
70
71 if (vp->v_flag & VALIASED) {
72 /*
73 * If a vgone (or vclean) is already in progress,
74 * wait until it is done and return.
75 */
76 if (vp->v_flag & VXLOCK) {
77 vp->v_flag |= VXWANT;
78 tsleep(vp, PINOD, "vop_generic_revokeall", 0);
79
80 return(0);
81 }
82
83 /*
84 * Ensure that vp will not be vgone'd while we
85 * are eliminating its aliases.
86 */
87 vp->v_flag |= VXLOCK;
88 while (vp->v_flag & VALIASED) {
89 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
90 if (vq->v_rdev != vp->v_rdev ||
91 vq->v_type != vp->v_type || vp == vq)
92 continue;
93 vgone(vq);
94 break;
95 }
96 }
97
98 /*
99 * Remove the lock so that vgone below will
100 * really eliminate the vnode after which time
101 * vgone will awaken any sleepers.
102 */
103 vp->v_flag &= ~VXLOCK;
104 }
105
106 vgonel(vp, p);
107
108 return (0);
109 }
110
111 int
112 vop_generic_bwrite(void *v)
113 {
114 struct vop_bwrite_args *ap = v;
115
116 return (bwrite(ap->a_bp));
117 }
118
119 int
120 vop_generic_abortop(void *v)
121 {
122 struct vop_abortop_args *ap = v;
123
124 if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
125 pool_put(&namei_pool, ap->a_cnp->cn_pnbuf);
126
127 return (0);
128 }
129
130 /*
131 * Stubs to use when there is no locking to be done on the underlying object.
132 * A minimal shared lock is necessary to ensure that the underlying object
133 * is not revoked while an operation is in progress. So, an active shared
134 * count should be maintained in an auxiliary vnode lock structure. However,
135 * that's not done now.
136 */
137 int
138 vop_generic_lock(void *v)
139 {
140 return (0);
141 }
142
143 /*
144 * Decrement the active use count. (Not done currently)
145 */
146 int
147 vop_generic_unlock(void *v)
148 {
149 return (0);
150 }
151
152 /*
153 * Return whether or not the node is in use. (Not done currently)
154 */
155 int
156 vop_generic_islocked(void *v)
157 {
158 return (0);
159 }
160
161 struct filterops generic_filtops =
162 { 1, NULL, filt_generic_detach, filt_generic_readwrite };
163
164 int
165 vop_generic_kqfilter(void *v)
166 {
167 struct vop_kqfilter_args *ap = v;
168 struct knote *kn = ap->a_kn;
169
170 switch (kn->kn_filter) {
171 case EVFILT_READ:
172 case EVFILT_WRITE:
173 kn->kn_fop = &generic_filtops;
174 break;
175 default:
176 return (1);
177 }
178
179 return (0);
180 }
181
182 void
183 filt_generic_detach(struct knote *kn)
184 {
185 }
186
187 int
188 filt_generic_readwrite(struct knote *kn, long hint)
189 {
190 /*
191 * filesystem is gone, so set the EOF flag and schedule
192 * the knote for deletion.
193 */
194 if (hint == NOTE_REVOKE) {
195 kn->kn_flags |= (EV_EOF | EV_ONESHOT);
196 return (1);
197 }
198
199 kn->kn_data = 0;
200
201 return (1);
202 }