Line data Source code
1 : /* $OpenBSD: vfs_default.c,v 1.43 2017/01/10 19:48:32 bluhm 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/mount.h>
42 : #include <sys/vnode.h>
43 : #include <sys/namei.h>
44 : #include <sys/pool.h>
45 : #include <sys/event.h>
46 : #include <sys/specdev.h>
47 :
48 : int filt_generic_readwrite(struct knote *, long);
49 : void filt_generic_detach(struct knote *);
50 :
51 : /*
52 : * Eliminate all activity associated with the requested vnode
53 : * and with all vnodes aliased to the requested vnode.
54 : */
55 : int
56 0 : vop_generic_revoke(void *v)
57 : {
58 0 : struct vop_revoke_args *ap = v;
59 : struct vnode *vp, *vq;
60 0 : struct proc *p = curproc;
61 :
62 : #ifdef DIAGNOSTIC
63 0 : if ((ap->a_flags & REVOKEALL) == 0)
64 0 : panic("vop_generic_revoke");
65 : #endif
66 :
67 0 : vp = ap->a_vp;
68 :
69 0 : while (vp->v_type == VBLK && vp->v_specinfo != NULL &&
70 0 : vp->v_specmountpoint != NULL) {
71 : struct mount *mp = vp->v_specmountpoint;
72 :
73 : /*
74 : * If we have a mount point associated with the vnode, we must
75 : * flush it out now, as to not leave a dangling zombie mount
76 : * point laying around in VFS.
77 : */
78 0 : if (!vfs_busy(mp, VB_WRITE|VB_WAIT)) {
79 0 : dounmount(mp, MNT_FORCE | MNT_DOOMED, p);
80 0 : break;
81 : }
82 0 : }
83 :
84 0 : if (vp->v_flag & VALIASED) {
85 : /*
86 : * If a vgone (or vclean) is already in progress,
87 : * wait until it is done and return.
88 : */
89 0 : if (vp->v_flag & VXLOCK) {
90 0 : vp->v_flag |= VXWANT;
91 0 : tsleep(vp, PINOD, "vop_generic_revokeall", 0);
92 :
93 0 : return(0);
94 : }
95 :
96 : /*
97 : * Ensure that vp will not be vgone'd while we
98 : * are eliminating its aliases.
99 : */
100 0 : vp->v_flag |= VXLOCK;
101 0 : while (vp->v_flag & VALIASED) {
102 0 : for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
103 0 : if (vq->v_rdev != vp->v_rdev ||
104 0 : vq->v_type != vp->v_type || vp == vq)
105 : continue;
106 0 : vgone(vq);
107 0 : break;
108 : }
109 : }
110 :
111 : /*
112 : * Remove the lock so that vgone below will
113 : * really eliminate the vnode after which time
114 : * vgone will awaken any sleepers.
115 : */
116 0 : vp->v_flag &= ~VXLOCK;
117 0 : }
118 :
119 0 : vgonel(vp, p);
120 :
121 0 : return (0);
122 0 : }
123 :
124 : int
125 0 : vop_generic_bmap(void *v)
126 : {
127 0 : struct vop_bmap_args *ap = v;
128 :
129 0 : if (ap->a_vpp)
130 0 : *ap->a_vpp = ap->a_vp;
131 0 : if (ap->a_bnp)
132 0 : *ap->a_bnp = ap->a_bn;
133 0 : if (ap->a_runp)
134 0 : *ap->a_runp = 0;
135 :
136 0 : return (0);
137 : }
138 :
139 : int
140 0 : vop_generic_bwrite(void *v)
141 : {
142 0 : struct vop_bwrite_args *ap = v;
143 :
144 0 : return (bwrite(ap->a_bp));
145 : }
146 :
147 : int
148 0 : vop_generic_abortop(void *v)
149 : {
150 0 : struct vop_abortop_args *ap = v;
151 :
152 0 : if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
153 0 : pool_put(&namei_pool, ap->a_cnp->cn_pnbuf);
154 :
155 0 : return (0);
156 : }
157 :
158 : /*
159 : * Stubs to use when there is no locking to be done on the underlying object.
160 : * A minimal shared lock is necessary to ensure that the underlying object
161 : * is not revoked while an operation is in progress. So, an active shared
162 : * count should be maintained in an auxiliary vnode lock structure. However,
163 : * that's not done now.
164 : */
165 : int
166 0 : vop_generic_lock(void *v)
167 : {
168 0 : return (0);
169 : }
170 :
171 : /*
172 : * Decrement the active use count. (Not done currently)
173 : */
174 : int
175 0 : vop_generic_unlock(void *v)
176 : {
177 0 : return (0);
178 : }
179 :
180 : /*
181 : * Return whether or not the node is in use. (Not done currently)
182 : */
183 : int
184 0 : vop_generic_islocked(void *v)
185 : {
186 0 : return (0);
187 : }
188 :
189 : struct filterops generic_filtops =
190 : { 1, NULL, filt_generic_detach, filt_generic_readwrite };
191 :
192 : int
193 0 : vop_generic_kqfilter(void *v)
194 : {
195 0 : struct vop_kqfilter_args *ap = v;
196 0 : struct knote *kn = ap->a_kn;
197 :
198 0 : switch (kn->kn_filter) {
199 : case EVFILT_READ:
200 : case EVFILT_WRITE:
201 0 : kn->kn_fop = &generic_filtops;
202 : break;
203 : default:
204 0 : return (EINVAL);
205 : }
206 :
207 0 : return (0);
208 0 : }
209 :
210 : /* Trivial lookup routine that always fails. */
211 : int
212 0 : vop_generic_lookup(void *v)
213 : {
214 0 : struct vop_lookup_args *ap = v;
215 :
216 0 : *ap->a_vpp = NULL;
217 0 : return (ENOTDIR);
218 : }
219 :
220 : void
221 0 : filt_generic_detach(struct knote *kn)
222 : {
223 0 : }
224 :
225 : int
226 0 : filt_generic_readwrite(struct knote *kn, long hint)
227 : {
228 : /*
229 : * filesystem is gone, so set the EOF flag and schedule
230 : * the knote for deletion.
231 : */
232 0 : if (hint == NOTE_REVOKE) {
233 0 : kn->kn_flags |= (EV_EOF | EV_ONESHOT);
234 0 : return (1);
235 : }
236 :
237 0 : kn->kn_data = 0;
238 :
239 0 : return (1);
240 0 : }
|