vnode_if.sh revision 1.1 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 # from: @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
35 # $Id: vnode_if.sh,v 1.1 1994/06/08 11:29:01 mycroft Exp $
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 inline struct.
117 printf("static inline int %s(", uname);
118 sep = ", ";
119 for (c2 = 0; c2 < c1; ++c2) {
120 if (c2 == c1 - 1)
121 sep = ")\n";
122 c3 = split(a[c2], t);
123 beg = match(t[c3], "[^*]");
124 end = match(t[c3], ";");
125 printf("%s%s", substr(t[c3], beg, end - beg), sep);
126 }
127 for (c2 = 0; c2 < c1; ++c2) {
128 c3 = split(a[c2], t);
129 printf("\t");
130 if (t[2] ~ "WILLRELE")
131 c4 = 3;
132 else
133 c4 = 2;
134 for (; c4 < c3; ++c4)
135 printf("%s ", t[c4]);
136 beg = match(t[c3], "[^*]");
137 printf("%s%s\n",
138 substr(t[c4], 0, beg - 1), substr(t[c4], beg));
139 }
140 printf("{\n\tstruct %s_args a;\n\n", name);
141 printf("\ta.a_desc = VDESC(%s);\n", name);
142 for (c2 = 0; c2 < c1; ++c2) {
143 c3 = split(a[c2], t);
144 printf("\t");
145 beg = match(t[c3], "[^*]");
146 end = match(t[c3], ";");
147 printf("a.a_%s = %s\n",
148 substr(t[c3], beg, end - beg), substr(t[c3], beg));
149 }
150 c1 = split(a[0], t);
151 beg = match(t[c1], "[^*]");
152 end = match(t[c1], ";");
153 printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n",
154 substr(t[c1], beg, end - beg), name);
155 }' < $SRC >> $HEADER
156
157 # Print out header information for vnode_if.c.
158 cat << END_OF_LEADING_COMMENT > $CFILE
159 /*
160 * This file is produced automatically.
161 * Do not modify anything in here by hand.
162 *
163 * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
164 */
165
166 #include <sys/param.h>
167 #include <sys/mount.h>
168 #include <sys/vnode.h>
169
170 struct vnodeop_desc vop_default_desc = {
171 0,
172 "default",
173 0,
174 NULL,
175 VDESC_NO_OFFSET,
176 VDESC_NO_OFFSET,
177 VDESC_NO_OFFSET,
178 VDESC_NO_OFFSET,
179 NULL,
180 };
181
182 END_OF_LEADING_COMMENT
183
184 # Awk script to take vnode_if.src and turn it into vnode_if.c.
185 $AWK 'function kill_surrounding_ws (s) {
186 sub (/^[ \t]*/, "", s);
187 sub (/[ \t]*$/, "", s);
188 return s;
189 }
190
191 function read_args() {
192 numargs = 0;
193 while (getline ln) {
194 if (ln ~ /}/) {
195 break;
196 };
197
198 # Delete comments, if any.
199 gsub (/\/\*.*\*\//, "", ln);
200
201 # Delete leading/trailing space.
202 ln = kill_surrounding_ws(ln);
203
204 # Pick off direction.
205 if (1 == sub(/^INOUT[ \t]+/, "", ln))
206 dir = "INOUT";
207 else if (1 == sub(/^IN[ \t]+/, "", ln))
208 dir = "IN";
209 else if (1 == sub(/^OUT[ \t]+/, "", ln))
210 dir = "OUT";
211 else
212 bail("No IN/OUT direction for \"" ln "\".");
213
214 # check for "WILLRELE"
215 if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) {
216 rele = "WILLRELE";
217 } else {
218 rele = "WONTRELE";
219 };
220
221 # kill trailing ;
222 if (1 != sub (/;$/, "", ln)) {
223 bail("Missing end-of-line ; in \"" ln "\".");
224 };
225
226 # pick off variable name
227 if (!(i = match(ln, /[A-Za-z0-9_]+$/))) {
228 bail("Missing var name \"a_foo\" in \"" ln "\".");
229 };
230 arg = substr (ln, i);
231 # Want to <<substr(ln, i) = "";>>, but nawk cannot.
232 # Hack around this.
233 ln = substr(ln, 1, i-1);
234
235 # what is left must be type
236 # (put clean it up some)
237 type = ln;
238 gsub (/[ \t]+/, " ", type); # condense whitespace
239 type = kill_surrounding_ws(type);
240
241 # (boy this was easier in Perl)
242
243 numargs++;
244 dirs[numargs] = dir;
245 reles[numargs] = rele;
246 types[numargs] = type;
247 args[numargs] = arg;
248 };
249 }
250
251 function generate_operation_vp_offsets() {
252 printf ("int %s_vp_offsets[] = {\n", name);
253 # as a side effect, figure out the releflags
254 releflags = "";
255 vpnum = 0;
256 for (i=1; i<=numargs; i++) {
257 if (types[i] == "struct vnode *") {
258 printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
259 name, args[i]);
260 if (reles[i] == "WILLRELE") {
261 releflags = releflags "|VDESC_VP" vpnum "_WILLRELE";
262 };
263 vpnum++;
264 };
265 };
266 sub (/^\|/, "", releflags);
267 print "\tVDESC_NO_OFFSET";
268 print "};";
269 }
270
271 function find_arg_with_type (type) {
272 for (i=1; i<=numargs; i++) {
273 if (types[i] == type) {
274 return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")";
275 };
276 };
277 return "VDESC_NO_OFFSET";
278 }
279
280 function generate_operation_desc() {
281 printf ("struct vnodeop_desc %s_desc = {\n", name);
282 # offset
283 printf ("\t0,\n");
284 # printable name
285 printf ("\t\"%s\",\n", name);
286 # flags
287 vppwillrele = "";
288 for (i=1; i<=numargs; i++) {
289 if (types[i] == "struct vnode **" &&
290 (reles[i] == "WILLRELE")) {
291 vppwillrele = "|VDESC_VPP_WILLRELE";
292 };
293 };
294 if (releflags == "") {
295 printf ("\t0%s,\n", vppwillrele);
296 } else {
297 printf ("\t%s%s,\n", releflags, vppwillrele);
298 };
299 # vp offsets
300 printf ("\t%s_vp_offsets,\n", name);
301 # vpp (if any)
302 printf ("\t%s,\n", find_arg_with_type("struct vnode **"));
303 # cred (if any)
304 printf ("\t%s,\n", find_arg_with_type("struct ucred *"));
305 # proc (if any)
306 printf ("\t%s,\n", find_arg_with_type("struct proc *"));
307 # componentname
308 printf ("\t%s,\n", find_arg_with_type("struct componentname *"));
309 # transport layer information
310 printf ("\tNULL,\n};\n");
311 }
312
313 NF == 0 || $0 ~ "^#" {
314 next;
315 }
316 {
317 # get the function name
318 name = $1;
319
320 # get the function arguments
321 read_args();
322
323 # Print out the vop_F_vp_offsets structure. This all depends
324 # on naming conventions and nothing else.
325 generate_operation_vp_offsets();
326
327 # Print out the vnodeop_desc structure.
328 generate_operation_desc();
329
330 printf "\n";
331
332 }' < $SRC >> $CFILE
333 # THINGS THAT DON'T WORK RIGHT YET.
334 #
335 # Two existing BSD vnodeops (bwrite and strategy) don't take any vnodes as
336 # arguments. This means that these operations can't function successfully
337 # through a bypass routine.
338 #
339 # Bwrite and strategy will be replaced when the VM page/buffer cache
340 # integration happens.
341 #
342 # To get around this problem for now we handle these ops as special cases.
343
344 cat << END_OF_SPECIAL_CASES >> $HEADER
345 #include <sys/buf.h>
346 struct vop_strategy_args {
347 struct vnodeop_desc *a_desc;
348 struct buf *a_bp;
349 };
350 extern struct vnodeop_desc vop_strategy_desc;
351 static inline int VOP_STRATEGY(bp)
352 struct buf *bp;
353 {
354 struct vop_strategy_args a;
355
356 a.a_desc = VDESC(vop_strategy);
357 a.a_bp = bp;
358 return (VCALL((bp)->b_vp, VOFFSET(vop_strategy), &a));
359 }
360
361 struct vop_bwrite_args {
362 struct vnodeop_desc *a_desc;
363 struct buf *a_bp;
364 };
365 extern struct vnodeop_desc vop_bwrite_desc;
366 static inline int VOP_BWRITE(bp)
367 struct buf *bp;
368 {
369 struct vop_bwrite_args a;
370
371 a.a_desc = VDESC(vop_bwrite);
372 a.a_bp = bp;
373 return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a));
374 }
375 END_OF_SPECIAL_CASES
376
377 cat << END_OF_SPECIAL_CASES >> $CFILE
378 int vop_strategy_vp_offsets[] = {
379 VDESC_NO_OFFSET
380 };
381 struct vnodeop_desc vop_strategy_desc = {
382 0,
383 "vop_strategy",
384 0,
385 vop_strategy_vp_offsets,
386 VDESC_NO_OFFSET,
387 VDESC_NO_OFFSET,
388 VDESC_NO_OFFSET,
389 VDESC_NO_OFFSET,
390 NULL,
391 };
392 int vop_bwrite_vp_offsets[] = {
393 VDESC_NO_OFFSET
394 };
395 struct vnodeop_desc vop_bwrite_desc = {
396 0,
397 "vop_bwrite",
398 0,
399 vop_bwrite_vp_offsets,
400 VDESC_NO_OFFSET,
401 VDESC_NO_OFFSET,
402 VDESC_NO_OFFSET,
403 VDESC_NO_OFFSET,
404 NULL,
405 };
406 END_OF_SPECIAL_CASES
407
408 # Add the vfs_op_descs array to the C file.
409 $AWK '
410 BEGIN {
411 printf("\nstruct vnodeop_desc *vfs_op_descs[] = {\n");
412 printf("\t&vop_default_desc, /* MUST BE FIRST */\n");
413 printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n");
414 printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n");
415 }
416 END {
417 printf("\tNULL\n};\n");
418 }
419 NF == 0 || $0 ~ "^#" {
420 next;
421 }
422 {
423 # Get the function name.
424 printf("\t&%s_desc,\n", $1);
425
426 # Skip the function arguments.
427 for (;;) {
428 if (getline <= 0)
429 exit
430 if ($0 ~ "^};")
431 break;
432 }
433 }' < $SRC >> $CFILE
434
435