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: src/sys/kern/vnode_if.sh,v 1.9.4.2 1999/09/05 08:15:48 peter 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 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/mount.h>
189 #include <sys/vnode.h>
190
191 struct vnodeop_desc vop_default_desc = {
192 0,
193 "default",
194 0,
195 NULL,
196 VDESC_NO_OFFSET,
197 VDESC_NO_OFFSET,
198 VDESC_NO_OFFSET,
199 VDESC_NO_OFFSET,
200 NULL,
201 };
202
203 END_OF_LEADING_COMMENT
204
205 # Awk script to take vnode_if.src and turn it into vnode_if.c.
206 $AWK 'function kill_surrounding_ws (s) {
207 sub (/^[ \t]*/, "", s);
208 sub (/[ \t]*$/, "", s);
209 return s;
210 }
211
212 function read_args() {
213 numargs = 0;
214 while (getline ln) {
215 if (ln ~ /}/) {
216 break;
217 };
218
219 # Delete comments, if any.
220 gsub (/\/\*.*\*\//, "", ln);
221
222 # Delete leading/trailing space.
223 ln = kill_surrounding_ws(ln);
224
225 # Pick off direction.
226 if (1 == sub(/^INOUT[ \t]+/, "", ln))
227 dir = "INOUT";
228 else if (1 == sub(/^IN[ \t]+/, "", ln))
229 dir = "IN";
230 else if (1 == sub(/^OUT[ \t]+/, "", ln))
231 dir = "OUT";
232 else
233 bail("No IN/OUT direction for \"" ln "\".");
234
235 # check for "WILLRELE"
236 if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) {
237 rele = "WILLRELE";
238 } else {
239 rele = "WONTRELE";
240 };
241
242 # kill trailing ;
243 if (1 != sub (/;$/, "", ln)) {
244 bail("Missing end-of-line ; in \"" ln "\".");
245 };
246
247 # pick off variable name
248 if (!(i = match(ln, /[A-Za-z0-9_]+$/))) {
249 bail("Missing var name \"a_foo\" in \"" ln "\".");
250 };
251 arg = substr (ln, i);
252 # Want to <<substr(ln, i) = "";>>, but nawk cannot.
253 # Hack around this.
254 ln = substr(ln, 1, i-1);
255
256 # what is left must be type
257 # (put clean it up some)
258 type = ln;
259 gsub (/[ \t]+/, " ", type); # condense whitespace
260 type = kill_surrounding_ws(type);
261
262 # (boy this was easier in Perl)
263
264 numargs++;
265 dirs[numargs] = dir;
266 reles[numargs] = rele;
267 types[numargs] = type;
268 args[numargs] = arg;
269 };
270 }
271
272 function generate_operation_vp_offsets() {
273 printf ("static int %s_vp_offsets[] = {\n", name);
274 # as a side effect, figure out the releflags
275 releflags = "";
276 vpnum = 0;
277 for (i=1; i<=numargs; i++) {
278 if (types[i] == "struct vnode *") {
279 printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
280 name, args[i]);
281 if (reles[i] == "WILLRELE") {
282 releflags = releflags "|VDESC_VP" vpnum "_WILLRELE";
283 };
284 vpnum++;
285 };
286 };
287 sub (/^\|/, "", releflags);
288 print "\tVDESC_NO_OFFSET";
289 print "};";
290 }
291
292 function find_arg_with_type (type) {
293 for (i=1; i<=numargs; i++) {
294 if (types[i] == type) {
295 return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")";
296 };
297 };
298 return "VDESC_NO_OFFSET";
299 }
300
301 function generate_operation_desc() {
302 printf ("struct vnodeop_desc %s_desc = {\n", name);
303 # offset
304 printf ("\t0,\n");
305 # printable name
306 printf ("\t\"%s\",\n", name);
307 # flags
308 vppwillrele = "";
309 for (i=1; i<=numargs; i++) {
310 if (types[i] == "struct vnode **" &&
311 (reles[i] == "WILLRELE")) {
312 vppwillrele = "|VDESC_VPP_WILLRELE";
313 };
314 };
315 if (releflags == "") {
316 printf ("\t0%s,\n", vppwillrele);
317 } else {
318 printf ("\t%s%s,\n", releflags, vppwillrele);
319 };
320 # vp offsets
321 printf ("\t%s_vp_offsets,\n", name);
322 # vpp (if any)
323 printf ("\t%s,\n", find_arg_with_type("struct vnode **"));
324 # cred (if any)
325 printf ("\t%s,\n", find_arg_with_type("struct ucred *"));
326 # proc (if any)
327 printf ("\t%s,\n", find_arg_with_type("struct proc *"));
328 # componentname
329 printf ("\t%s,\n", find_arg_with_type("struct componentname *"));
330 # transport layer information
331 printf ("\tNULL,\n};\n");
332 }
333
334 NF == 0 || $0 ~ "^#" {
335 next;
336 }
337 {
338 # get the function name
339 name = $1;
340
341 # get the function arguments
342 read_args();
343
344 # Print out the vop_F_vp_offsets structure. This all depends
345 # on naming conventions and nothing else.
346 generate_operation_vp_offsets();
347
348 # Print out the vnodeop_desc structure.
349 generate_operation_desc();
350
351 printf "\n";
352
353 }' < $SRC >> $CFILE
354 # THINGS THAT DON'T WORK RIGHT YET.
355 #
356 # Two existing BSD vnodeops (bwrite and strategy) don't take any vnodes as
357 # arguments. This means that these operations can't function successfully
358 # through a bypass routine.
359 #
360 # Bwrite and strategy will be replaced when the VM page/buffer cache
361 # integration happens.
362 #
363 # To get around this problem for now we handle these ops as special cases.
364
365 cat << END_OF_SPECIAL_CASES >> $HEADER
366 #include <sys/buf.h>
367 struct vop_strategy_args {
368 struct vnodeop_desc *a_desc;
369 struct buf *a_bp;
370 };
371 extern struct vnodeop_desc vop_strategy_desc;
372 static int VOP_STRATEGY __P((
373 struct buf *bp));
374 static __inline int VOP_STRATEGY(bp)
375 struct buf *bp;
376 {
377 struct vop_strategy_args a;
378
379 a.a_desc = VDESC(vop_strategy);
380 a.a_bp = bp;
381 return (VCALL((bp)->b_vp, VOFFSET(vop_strategy), &a));
382 }
383
384 struct vop_bwrite_args {
385 struct vnodeop_desc *a_desc;
386 struct buf *a_bp;
387 };
388 extern struct vnodeop_desc vop_bwrite_desc;
389 static int VOP_BWRITE __P((
390 struct buf *bp));
391 static __inline int VOP_BWRITE(bp)
392 struct buf *bp;
393 {
394 struct vop_bwrite_args a;
395
396 a.a_desc = VDESC(vop_bwrite);
397 a.a_bp = bp;
398 return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a));
399 }
400 END_OF_SPECIAL_CASES
401
402 cat << END_OF_SPECIAL_CASES >> $CFILE
403 static int vop_strategy_vp_offsets[] = {
404 VDESC_NO_OFFSET
405 };
406 struct vnodeop_desc vop_strategy_desc = {
407 0,
408 "vop_strategy",
409 0,
410 vop_strategy_vp_offsets,
411 VDESC_NO_OFFSET,
412 VDESC_NO_OFFSET,
413 VDESC_NO_OFFSET,
414 VDESC_NO_OFFSET,
415 NULL,
416 };
417 static int vop_bwrite_vp_offsets[] = {
418 VDESC_NO_OFFSET
419 };
420 struct vnodeop_desc vop_bwrite_desc = {
421 0,
422 "vop_bwrite",
423 0,
424 vop_bwrite_vp_offsets,
425 VDESC_NO_OFFSET,
426 VDESC_NO_OFFSET,
427 VDESC_NO_OFFSET,
428 VDESC_NO_OFFSET,
429 NULL,
430 };
431 END_OF_SPECIAL_CASES
432
433 # Add the vfs_op_descs array to the C file.
434 $AWK '
435 BEGIN {
436 printf("\nstruct vnodeop_desc *vfs_op_descs[] = {\n");
437 printf("\t&vop_default_desc, /* MUST BE FIRST */\n");
438 printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n");
439 printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n");
440 }
441 END {
442 printf("\tNULL\n};\n");
443 }
444 NF == 0 || $0 ~ "^#" {
445 next;
446 }
447 {
448 # Get the function name.
449 printf("\t&%s_desc,\n", $1);
450
451 # Skip the function arguments.
452 for (;;) {
453 if (getline <= 0)
454 exit
455 if ($0 ~ "^};")
456 break;
457 }
458 }' < $SRC >> $CFILE
459
Cache object: df46361c2e4fd1a31c7c4197aa7877c6
|