FreeBSD/Linux Kernel Cross Reference
sys/kern/vnode_if.sh
1 #!/bin/sh -
2 copyright="\
3 /*
4 * Copyright (c) 1992, 1993, 1994, 1995
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \`\`AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31 "
32 SCRIPT_ID='$NetBSD: vnode_if.sh,v 1.34 2004/01/25 18:02:04 hannken Exp $'
33
34 # Script to produce VFS front-end sugar.
35 #
36 # usage: vnode_if.sh srcfile
37 # (where srcfile is currently /sys/kern/vnode_if.src)
38 #
39
40 if [ $# -ne 1 ] ; then
41 echo 'usage: vnode_if.sh srcfile'
42 exit 1
43 fi
44
45 # Name and revision of the source file.
46 src=$1
47 SRC_ID=`head -1 $src | sed -e 's/.*\$\(.*\)\$.*/\1/'`
48
49 # Names of the created files.
50 out_c=vnode_if.c
51 out_h=../sys/vnode_if.h
52
53 # Awk program (must support nawk extensions)
54 # Use "awk" at Berkeley, "nawk" or "gawk" elsewhere.
55 awk=${AWK:-awk}
56
57 # Does this awk have a "toupper" function? (i.e. is it GNU awk)
58 isgawk=`$awk 'BEGIN { print toupper("true"); exit; }' 2>/dev/null`
59
60 # If this awk does not define "toupper" then define our own.
61 if [ "$isgawk" = TRUE ] ; then
62 # GNU awk provides it.
63 toupper=
64 else
65 # Provide our own toupper()
66 toupper='
67 function toupper(str) {
68 _toupper_cmd = "echo "str" |tr a-z A-Z"
69 _toupper_cmd | getline _toupper_str;
70 close(_toupper_cmd);
71 return _toupper_str;
72 }'
73 fi
74
75 #
76 # This is the common part of all awk programs that read $src
77 # This parses the input for one function into the arrays:
78 # argdir, argtype, argname, willrele
79 # and calls "doit()" to generate output for the function.
80 #
81 # Input to this parser is pre-processed slightly by sed
82 # so this awk parser doesn't have to work so hard. The
83 # changes done by the sed pre-processing step are:
84 # insert a space beween * and pointer name
85 # replace semicolons with spaces
86 #
87 sed_prep='s:\*\([^\*/]\):\* \1:g
88 s/;/ /'
89 awk_parser='
90 # Comment line
91 /^#/ { next; }
92 # First line of description
93 /^vop_/ {
94 name=$1;
95 argc=0;
96 next;
97 }
98 # Last line of description
99 /^}/ {
100 doit();
101 next;
102 }
103 # Middle lines of description
104 {
105 argdir[argc] = $1; i=2;
106 if ($2 == "WILLRELE") {
107 willrele[argc] = 1;
108 i++;
109 } else if ($2 == "WILLUNLOCK") {
110 willrele[argc] = 2;
111 i++;
112 } else if ($2 == "WILLPUT") {
113 willrele[argc] = 3;
114 i++;
115 } else
116 willrele[argc] = 0;
117 argtype[argc] = $i; i++;
118 while (i < NF) {
119 argtype[argc] = argtype[argc]" "$i;
120 i++;
121 }
122 argname[argc] = $i;
123 argc++;
124 next;
125 }
126 '
127
128 # This is put before the copyright on each generated file.
129 warning="\
130 /* @NetBSD@ */
131
132 /*
133 * Warning: This file is generated automatically.
134 * (Modifications made here may easily be lost!)
135 *
136 * Created from the file:
137 * ${SRC_ID}
138 * by the script:
139 * ${SCRIPT_ID}
140 */
141 "
142
143 # This is to satisfy McKusick (get rid of evil spaces 8^)
144 anal_retentive='s:\([^/]\*\) :\1:g'
145
146 #
147 # Redirect stdout to the H file.
148 #
149 echo "$0: Creating $out_h" 1>&2
150 exec > $out_h
151
152 # Begin stuff
153 echo -n "$warning" | sed -e 's/\$//g;s/@/\$/g'
154 echo ""
155 echo -n "$copyright"
156 echo ''
157 echo '#ifndef _SYS_VNODE_IF_H_'
158 echo '#define _SYS_VNODE_IF_H_'
159 echo ''
160 echo '#ifdef _KERNEL'
161 echo '#if defined(_LKM) || defined(LKM)'
162 echo '/* LKMs always use non-inlined vnode ops. */'
163 echo '#define VNODE_OP_NOINLINE'
164 echo '#else'
165 echo '#include "opt_vnode_op_noinline.h"'
166 echo '#endif'
167 echo '#endif /* _KERNEL */'
168 echo '
169 extern const struct vnodeop_desc vop_default_desc;
170 '
171
172 # Body stuff
173 # This awk program needs toupper() so define it if necessary.
174 sed -e "$sed_prep" $src | $awk "$toupper"'
175 function doit() {
176 # Declare arg struct, descriptor.
177 printf("\nstruct %s_args {\n", name);
178 printf("\tconst struct vnodeop_desc * a_desc;\n");
179 for (i=0; i<argc; i++) {
180 printf("\t%s a_%s;\n", argtype[i], argname[i]);
181 }
182 printf("};\n");
183 printf("extern const struct vnodeop_desc %s_desc;\n", name);
184 # Prototype it.
185 printf("#ifndef VNODE_OP_NOINLINE\n");
186 printf("static __inline\n");
187 printf("#endif\n");
188 protoarg = sprintf("int %s(", toupper(name));
189 protolen = length(protoarg);
190 printf("%s", protoarg);
191 for (i=0; i<argc; i++) {
192 protoarg = sprintf("%s", argtype[i]);
193 if (i < (argc-1)) protoarg = (protoarg ", ");
194 arglen = length(protoarg);
195 if ((protolen + arglen) > 77) {
196 protoarg = ("\n " protoarg);
197 arglen += 4;
198 protolen = 0;
199 }
200 printf("%s", protoarg);
201 protolen += arglen;
202 }
203 printf(")\n");
204 printf("#ifndef VNODE_OP_NOINLINE\n");
205 printf("__attribute__((__unused__))\n");
206 printf("#endif\n");
207 printf(";\n");
208 # Define inline function.
209 printf("#ifndef VNODE_OP_NOINLINE\n");
210 printf("static __inline int %s(", toupper(name));
211 for (i=0; i<argc; i++) {
212 printf("%s", argname[i]);
213 if (i < (argc-1)) printf(", ");
214 }
215 printf(")\n");
216 for (i=0; i<argc; i++) {
217 printf("\t%s %s;\n", argtype[i], argname[i]);
218 }
219 printf("{\n\tstruct %s_args a;\n", name);
220 printf("\ta.a_desc = VDESC(%s);\n", name);
221 for (i=0; i<argc; i++) {
222 printf("\ta.a_%s = %s;\n", argname[i], argname[i]);
223 }
224 printf("\treturn (VCALL(%s%s, VOFFSET(%s), &a));\n}\n",
225 argname[0], arg0special, name);
226 printf("#endif\n");
227 vops++;
228 }
229 BEGIN {
230 arg0special="";
231 vops = 1; # start at 1, to count the 'default' op
232 }
233 END {
234 printf("\n/* Special cases: */\n#include <sys/buf.h>\n");
235 argc=1;
236 argtype[0]="struct buf *";
237 argname[0]="bp";
238 arg0special="->b_vp";
239 name="vop_bwrite";
240 doit();
241
242 printf("\n#define VNODE_OPS_COUNT\t%d\n", vops);
243 }
244 '"$awk_parser" | sed -e "$anal_retentive"
245
246 # End stuff
247 echo '
248 /* End of special cases. */'
249 echo ''
250 echo '#endif /* !_SYS_VNODE_IF_H_ */'
251
252 #
253 # Redirect stdout to the C file.
254 #
255 echo "$0: Creating $out_c" 1>&2
256 exec > $out_c
257
258 # Begin stuff
259 echo -n "$warning" | sed -e 's/\$//g;s/@/\$/g'
260 echo ""
261 echo -n "$copyright"
262 echo "
263 #include <sys/cdefs.h>
264 __KERNEL_RCSID(0, \"\$NetBSD\$\");
265 "
266
267 echo '
268 /*
269 * If we have LKM support, always include the non-inline versions for
270 * LKMs. Otherwise, do it based on the option.
271 */
272 #ifdef LKM
273 #define VNODE_OP_NOINLINE
274 #else
275 #include "opt_vnode_op_noinline.h"
276 #endif'
277 echo '
278 #include <sys/param.h>
279 #include <sys/mount.h>
280 #include <sys/buf.h>
281 #include <sys/vnode.h>
282
283 const struct vnodeop_desc vop_default_desc = {
284 0,
285 "default",
286 0,
287 NULL,
288 VDESC_NO_OFFSET,
289 VDESC_NO_OFFSET,
290 VDESC_NO_OFFSET,
291 VDESC_NO_OFFSET,
292 NULL,
293 };
294 '
295
296 # Body stuff
297 sed -e "$sed_prep" $src | $awk '
298 function do_offset(typematch) {
299 for (i=0; i<argc; i++) {
300 if (argtype[i] == typematch) {
301 printf("\tVOPARG_OFFSETOF(struct %s_args, a_%s),\n",
302 name, argname[i]);
303 return i;
304 };
305 };
306 print "\tVDESC_NO_OFFSET,";
307 return -1;
308 }
309
310 function doit() {
311 # Define offsets array
312 printf("\nconst int %s_vp_offsets[] = {\n", name);
313 for (i=0; i<argc; i++) {
314 if (argtype[i] == "struct vnode *") {
315 printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
316 name, argname[i]);
317 }
318 }
319 print "\tVDESC_NO_OFFSET";
320 print "};";
321 # Define F_desc
322 printf("const struct vnodeop_desc %s_desc = {\n", name);
323 # offset
324 printf ("\t%d,\n", vop_offset++);
325 # printable name
326 printf ("\t\"%s\",\n", name);
327 # flags
328 printf("\t0");
329 vpnum = 0;
330 for (i=0; i<argc; i++) {
331 if (willrele[i]) {
332 if (willrele[i] == 2) {
333 word = "UNLOCK";
334 } else if (willrele[i] == 3) {
335 word = "PUT";
336 } else {
337 word = "RELE";
338 }
339 if (argdir[i] ~ /OUT/) {
340 printf(" | VDESC_VPP_WILL%s", word);
341 } else {
342 printf(" | VDESC_VP%s_WILL%s", vpnum, word);
343 };
344 vpnum++;
345 }
346 }
347 print ",";
348 # vp offsets
349 printf ("\t%s_vp_offsets,\n", name);
350 # vpp (if any)
351 do_offset("struct vnode **");
352 # cred (if any)
353 do_offset("struct ucred *");
354 # proc (if any)
355 do_offset("struct proc *");
356 # componentname
357 do_offset("struct componentname *");
358 # transport layer information
359 printf ("\tNULL,\n};\n");
360
361 # Define function.
362 printf("#ifdef VNODE_OP_NOINLINE\n");
363 printf("int\n%s(", toupper(name));
364 for (i=0; i<argc; i++) {
365 printf("%s", argname[i]);
366 if (i < (argc-1)) printf(", ");
367 }
368 printf(")\n");
369 for (i=0; i<argc; i++) {
370 printf("\t%s %s;\n", argtype[i], argname[i]);
371 }
372 printf("{\n\tstruct %s_args a;\n", name);
373 printf("\ta.a_desc = VDESC(%s);\n", name);
374 for (i=0; i<argc; i++) {
375 printf("\ta.a_%s = %s;\n", argname[i], argname[i]);
376 }
377 printf("\treturn (VCALL(%s%s, VOFFSET(%s), &a));\n}\n",
378 argname[0], arg0special, name);
379 printf("#endif\n");
380 }
381 BEGIN {
382 printf("\n/* Special cases: */\n");
383 # start from 1 (vop_default is at 0)
384 vop_offset=1;
385 argc=1;
386 argdir[0]="IN";
387 argtype[0]="struct buf *";
388 argname[0]="bp";
389 arg0special="->b_vp";
390 willrele[0]=0;
391 name="vop_bwrite";
392 doit();
393 printf("\n/* End of special cases */\n");
394
395 arg0special="";
396 }
397 '"$awk_parser" | sed -e "$anal_retentive"
398
399 # End stuff
400 echo '
401 /* End of special cases. */'
402
403 # Add the vfs_op_descs array to the C file.
404 # Begin stuff
405 echo '
406 const struct vnodeop_desc * const vfs_op_descs[] = {
407 &vop_default_desc, /* MUST BE FIRST */
408 &vop_bwrite_desc, /* XXX: SPECIAL CASE */
409 '
410
411 # Body stuff
412 sed -e "$sed_prep" $src | $awk '
413 function doit() {
414 printf("\t&%s_desc,\n", name);
415 }
416 '"$awk_parser"
417
418 # End stuff
419 echo ' NULL
420 };
421 '
422
423 exit 0
424
425 # Local Variables:
426 # tab-width: 4
427 # End:
Cache object: 095a13183d732f36586442014439cfc8
|