FreeBSD/Linux Kernel Cross Reference
sys/kern/vnode_if.sh
1 #!/bin/sh -
2 #
3 # Copyright (c) 1992, 1993
4 # The Regents of the University of California. All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 # 3. All advertising materials mentioning features or use of this software
15 # must display the following acknowledgement:
16 # This product includes software developed by the University of
17 # California, Berkeley and its contributors.
18 # 4. Neither the name of the University nor the names of its contributors
19 # may be used to endorse or promote products derived from this software
20 # without specific prior written permission.
21 #
22 # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 # SUCH DAMAGE.
33 #
34 # @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
35 # $FreeBSD$
36 #
37
38 # Script to produce VFS front-end sugar.
39 #
40 # usage: vnode_if.sh srcfile
41 # (where srcfile is currently /sys/kern/vnode_if.src)
42 #
43 # These awk scripts are not particularly well written, specifically they
44 # don't use arrays well and figure out the same information repeatedly.
45 # Please rewrite them if you actually understand how to use awk. Note,
46 # they use nawk extensions and gawk's toupper.
47
48 if [ $# -ne 1 ] ; then
49 echo 'usage: vnode_if.sh srcfile'
50 exit 1
51 fi
52
53 # Name of the source file.
54 SRC=$1
55
56 # Names of the created files.
57 CFILE=vnode_if.c
58 HEADER=vnode_if.h
59
60 # Awk program (must support nawk extensions and gawk's "toupper")
61 # Use "awk" at Berkeley, "gawk" elsewhere.
62 AWK=awk
63
64 # Print out header information for vnode_if.h.
65 cat << END_OF_LEADING_COMMENT > $HEADER
66 /*
67 * This file is produced automatically.
68 * Do not modify anything in here by hand.
69 *
70 * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
71 */
72
73 extern struct vnodeop_desc vop_default_desc;
74 END_OF_LEADING_COMMENT
75
76 # Awk script to take vnode_if.src and turn it into vnode_if.h.
77 $AWK '
78 NF == 0 || $0 ~ "^#" {
79 next;
80 }
81 {
82 # Get the function name.
83 name = $1;
84 uname = toupper(name);
85
86 # Get the function arguments.
87 for (c1 = 0;; ++c1) {
88 if (getline <= 0)
89 exit
90 if ($0 ~ "^};")
91 break;
92 a[c1] = $0;
93 }
94
95 # Print out the vop_F_args structure.
96 printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n",
97 name);
98 for (c2 = 0; c2 < c1; ++c2) {
99 c3 = split(a[c2], t);
100 printf("\t");
101 if (t[2] ~ "WILLRELE")
102 c4 = 3;
103 else
104 c4 = 2;
105 for (; c4 < c3; ++c4)
106 printf("%s ", t[c4]);
107 beg = match(t[c3], "[^*]");
108 printf("%sa_%s\n",
109 substr(t[c4], 0, beg - 1), substr(t[c4], beg));
110 }
111 printf("};\n");
112
113 # Print out extern declaration.
114 printf("extern struct vnodeop_desc %s_desc;\n", name);
115
116 # Print out prototype.
117 printf("static int %s __P((\n", uname);
118 sep = ",\n";
119 for (c2 = 0; c2 < c1; ++c2) {
120 if (c2 == c1 - 1)
121 sep = "));\n";
122 c3 = split(a[c2], t);
123 printf("\t");
124 if (t[2] ~ "WILLRELE")
125 c4 = 3;
126 else
127 c4 = 2;
128 for (; c4 < c3; ++c4)
129 printf("%s ", t[c4]);
130 beg = match(t[c3], "[^*]");
131 end = match(t[c3], ";");
132 printf("%s%s%s",
133 substr(t[c4], 0, beg - 1),
134 substr(t[c4], beg, end - beg), sep);
135 }
136
137 # Print out inline struct.
138 printf("static __inline int %s(", uname);
139 sep = ", ";
140 for (c2 = 0; c2 < c1; ++c2) {
141 if (c2 == c1 - 1)
142 sep = ")\n";
143 c3 = split(a[c2], t);
144 beg = match(t[c3], "[^*]");
145 end = match(t[c3], ";");
146 printf("%s%s", substr(t[c3], beg, end - beg), sep);
147 }
148 for (c2 = 0; c2 < c1; ++c2) {
149 c3 = split(a[c2], t);
150 printf("\t");
151 if (t[2] ~ "WILLRELE")
152 c4 = 3;
153 else
154 c4 = 2;
155 for (; c4 < c3; ++c4)
156 printf("%s ", t[c4]);
157 beg = match(t[c3], "[^*]");
158 printf("%s%s\n",
159 substr(t[c4], 0, beg - 1), substr(t[c4], beg));
160 }
161 printf("{\n\tstruct %s_args a;\n\n", name);
162 printf("\ta.a_desc = VDESC(%s);\n", name);
163 for (c2 = 0; c2 < c1; ++c2) {
164 c3 = split(a[c2], t);
165 printf("\t");
166 beg = match(t[c3], "[^*]");
167 end = match(t[c3], ";");
168 printf("a.a_%s = %s\n",
169 substr(t[c3], beg, end - beg), substr(t[c3], beg));
170 }
171 c1 = split(a[0], t);
172 beg = match(t[c1], "[^*]");
173 end = match(t[c1], ";");
174 printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n",
175 substr(t[c1], beg, end - beg), name);
176 }' < $SRC >> $HEADER
177
178 # Print out header information for vnode_if.c.
179 cat << END_OF_LEADING_COMMENT > $CFILE
180 /*
181 * This file is produced automatically.
182 * Do not modify anything in here by hand.
183 *
184 * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
185 */
186
187 #include <sys/param.h>
188 #include <sys/vnode.h>
189
190 struct vnodeop_desc vop_default_desc = {
191 1, /* special case, vop_default => 1 */
192 "default",
193 0,
194 NULL,
195 VDESC_NO_OFFSET,
196 VDESC_NO_OFFSET,
197 VDESC_NO_OFFSET,
198 VDESC_NO_OFFSET,
199 NULL,
200 };
201
202 END_OF_LEADING_COMMENT
203
204 # Awk script to take vnode_if.src and turn it into vnode_if.c.
205 $AWK 'function kill_surrounding_ws (s) {
206 sub (/^[ \t]*/, "", s);
207 sub (/[ \t]*$/, "", s);
208 return s;
209 }
210
211 function read_args() {
212 numargs = 0;
213 while (getline ln) {
214 if (ln ~ /}/) {
215 break;
216 };
217
218 # Delete comments, if any.
219 gsub (/\/\*.*\*\//, "", ln);
220
221 # Delete leading/trailing space.
222 ln = kill_surrounding_ws(ln);
223
224 # Pick off direction.
225 if (1 == sub(/^INOUT[ \t]+/, "", ln))
226 dir = "INOUT";
227 else if (1 == sub(/^IN[ \t]+/, "", ln))
228 dir = "IN";
229 else if (1 == sub(/^OUT[ \t]+/, "", ln))
230 dir = "OUT";
231 else
232 bail("No IN/OUT direction for \"" ln "\".");
233
234 # check for "WILLRELE"
235 if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) {
236 rele = "WILLRELE";
237 } else {
238 rele = "WONTRELE";
239 };
240
241 # kill trailing ;
242 if (1 != sub (/;$/, "", ln)) {
243 bail("Missing end-of-line ; in \"" ln "\".");
244 };
245
246 # pick off variable name
247 if (!(i = match(ln, /[A-Za-z0-9_]+$/))) {
248 bail("Missing var name \"a_foo\" in \"" ln "\".");
249 };
250 arg = substr (ln, i);
251 # Want to <<substr(ln, i) = "";>>, but nawk cannot.
252 # Hack around this.
253 ln = substr(ln, 1, i-1);
254
255 # what is left must be type
256 # (put clean it up some)
257 type = ln;
258 gsub (/[ \t]+/, " ", type); # condense whitespace
259 type = kill_surrounding_ws(type);
260
261 # (boy this was easier in Perl)
262
263 numargs++;
264 dirs[numargs] = dir;
265 reles[numargs] = rele;
266 types[numargs] = type;
267 args[numargs] = arg;
268 };
269 }
270
271 function generate_operation_vp_offsets() {
272 printf ("static int %s_vp_offsets[] = {\n", name);
273 # as a side effect, figure out the releflags
274 releflags = "";
275 vpnum = 0;
276 for (i=1; i<=numargs; i++) {
277 if (types[i] == "struct vnode *") {
278 printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
279 name, args[i]);
280 if (reles[i] == "WILLRELE") {
281 releflags = releflags "|VDESC_VP" vpnum "_WILLRELE";
282 };
283 vpnum++;
284 };
285 };
286 sub (/^\|/, "", releflags);
287 print "\tVDESC_NO_OFFSET";
288 print "};";
289 }
290
291 function find_arg_with_type (type) {
292 for (i=1; i<=numargs; i++) {
293 if (types[i] == type) {
294 return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")";
295 };
296 };
297 return "VDESC_NO_OFFSET";
298 }
299
300 function generate_operation_desc() {
301 printf ("struct vnodeop_desc %s_desc = {\n", name);
302 # offset
303 printf ("\t0,\n");
304 # printable name
305 printf ("\t\"%s\",\n", name);
306 # flags
307 vppwillrele = "";
308 for (i=1; i<=numargs; i++) {
309 if (types[i] == "struct vnode **" &&
310 (reles[i] == "WILLRELE")) {
311 vppwillrele = "|VDESC_VPP_WILLRELE";
312 };
313 };
314 if (releflags == "") {
315 printf ("\t0%s,\n", vppwillrele);
316 } else {
317 printf ("\t%s%s,\n", releflags, vppwillrele);
318 };
319 # vp offsets
320 printf ("\t%s_vp_offsets,\n", name);
321 # vpp (if any)
322 printf ("\t%s,\n", find_arg_with_type("struct vnode **"));
323 # cred (if any)
324 printf ("\t%s,\n", find_arg_with_type("struct ucred *"));
325 # proc (if any)
326 printf ("\t%s,\n", find_arg_with_type("struct proc *"));
327 # componentname
328 printf ("\t%s,\n", find_arg_with_type("struct componentname *"));
329 # transport layer information
330 printf ("\tNULL,\n};\n");
331 }
332
333 NF == 0 || $0 ~ "^#" {
334 next;
335 }
336 {
337 # get the function name
338 name = $1;
339
340 # get the function arguments
341 read_args();
342
343 # Print out the vop_F_vp_offsets structure. This all depends
344 # on naming conventions and nothing else.
345 generate_operation_vp_offsets();
346
347 # Print out the vnodeop_desc structure.
348 generate_operation_desc();
349
350 printf "\n";
351
352 }' < $SRC >> $CFILE
353 # THINGS THAT DON'T WORK RIGHT YET.
354 #
355 # Two existing BSD vnodeops (bwrite and strategy) don't take any vnodes as
356 # arguments. This means that these operations can't function successfully
357 # through a bypass routine.
358 #
359 # Bwrite and strategy will be replaced when the VM page/buffer cache
360 # integration happens.
361 #
362 # To get around this problem for now we handle these ops as special cases.
363
364 cat << END_OF_SPECIAL_CASES >> $HEADER
365 #include <sys/buf.h>
366
367 struct vop_bwrite_args {
368 struct vnodeop_desc *a_desc;
369 struct buf *a_bp;
370 };
371 extern struct vnodeop_desc vop_bwrite_desc;
372 static int VOP_BWRITE __P((
373 struct buf *bp));
374 static __inline int VOP_BWRITE(bp)
375 struct buf *bp;
376 {
377 struct vop_bwrite_args a;
378
379 a.a_desc = VDESC(vop_bwrite);
380 a.a_bp = bp;
381 return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a));
382 }
383
384 extern int vfs_opv_numops;
385 END_OF_SPECIAL_CASES
386
387 cat << END_OF_SPECIAL_CASES >> $CFILE
388 static int vop_bwrite_vp_offsets[] = {
389 VDESC_NO_OFFSET
390 };
391 struct vnodeop_desc vop_bwrite_desc = {
392 0,
393 "vop_bwrite",
394 0,
395 vop_bwrite_vp_offsets,
396 VDESC_NO_OFFSET,
397 VDESC_NO_OFFSET,
398 VDESC_NO_OFFSET,
399 VDESC_NO_OFFSET,
400 NULL,
401 };
402 END_OF_SPECIAL_CASES
Cache object: df63267cce93cc6cdb0dcde605369b1e
|