]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/vnode_if.pl
KSE Milestone 2
[FreeBSD/FreeBSD.git] / sys / kern / vnode_if.pl
1 #!/usr/bin/perl -w
2
3 #
4 # Copyright (c) 1992, 1993
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. All advertising materials mentioning features or use of this software
16 #    must display the following acknowledgement:
17 #       This product includes software developed by the University of
18 #       California, Berkeley and its contributors.
19 # 4. Neither the name of the University nor the names of its contributors
20 #    may be used to endorse or promote products derived from this software
21 #    without specific prior written permission.
22 #
23 # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 # ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 # SUCH DAMAGE.
34 #
35 #       @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
36 # $FreeBSD$
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
44 use strict;
45
46 my %lockdata;
47
48 my $cfile = 0;
49 my $hfile = 0;
50 my $srcfile;
51
52 # Process the command line
53 #
54 while (my $arg = shift @ARGV) {
55     if ($arg eq '-c') {
56         $cfile = 1;
57     } elsif ($arg eq '-h') {
58         $hfile = 1;
59     } elsif ($arg eq '-ch' || $arg eq '-hc') {
60         $cfile = 1;
61         $hfile = 1;
62     } elsif ($arg =~ m/\.src$/) {
63         $srcfile = $arg;
64     } else {
65         print "usage: vnode_if.sh [-c] [-h] srcfile\n";
66         exit(1);
67     }
68 }
69 if (!$cfile and !$hfile) {
70     exit(0);            # nothing asked for..
71 }
72
73 # Names of the created files.
74 my $CFILE='vnode_if.c';
75 my $HEADER='vnode_if.h';
76
77 open(SRC,     "<$srcfile")   || die "Unable to open input file";
78
79 if ($hfile) {
80     open(HEADER, ">$HEADER") || die "Unable to create $HEADER";
81     # Print out header information for vnode_if.h.
82     print HEADER <<END_OF_LEADING_COMMENT
83 /*
84  * This file is produced automatically.
85  * Do not modify anything in here by hand.
86  *
87  * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
88  */
89
90 extern struct vnodeop_desc vop_default_desc;
91 END_OF_LEADING_COMMENT
92     ;
93 }
94
95 if ($cfile) {
96     open(CFILE,   ">$CFILE") || die "Unable to create $CFILE";
97     # Print out header information for vnode_if.c.
98     print CFILE <<END_OF_LEADING_COMMENT
99 /*
100  * This file is produced automatically.
101  * Do not modify anything in here by hand.
102  *
103  * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
104  */
105
106 #include <sys/param.h>
107 #include <sys/vnode.h>
108
109 struct vnodeop_desc vop_default_desc = {
110         1,                      /* special case, vop_default => 1 */
111         "default",
112         0,
113         NULL,
114         VDESC_NO_OFFSET,
115         VDESC_NO_OFFSET,
116         VDESC_NO_OFFSET,
117         VDESC_NO_OFFSET,
118         NULL,
119 };
120
121 END_OF_LEADING_COMMENT
122     ;
123 }
124
125 my %a;
126 my %dirs;
127 my %reles;
128 my %types;
129 my %args;
130 my $numargs;
131 my $name;
132
133 line: while (<SRC>) {
134     chop;       # strip record separator
135     my @Fld = split ' ';
136     if (@Fld == 0) {
137         next line;
138     }
139     if (/^#/) {
140         if (!/^#%\s+([a-z]+)\s+([a-z]+)\s+(.)\s(.)\s(.)/) {
141             next;
142         }
143         if (!defined($lockdata{"vop_$1"})) {
144             $lockdata{"vop_$1"} = {};
145         }
146         $lockdata{"vop_$1"}->{$2} = {
147             'Entry' => $3,
148             'OK'    => $4,
149             'Error' => $5,
150         };
151         next;
152     }
153
154     # Get the function name.
155     $name = $Fld[0];
156     my $uname = uc($name);
157     my $ln;
158     # Get the function arguments.
159     for ($numargs = 0; ; ++$numargs) {
160         if ($ln = <SRC>) {
161             chomp;
162         } else {
163             die "Unable to read through the arguments for \"$name\"";
164         }
165         if ($ln =~ /^\};/) {
166             last;
167         }
168         # For the header file
169         $a{$numargs} = $ln;
170
171         # The rest of this loop is for the C file
172         # Delete comments, if any.
173         $ln =~ s/\/\*.*\*\///g;
174
175         # Delete leading/trailing space.
176         $ln =~ s/^\s*(.*?)\s*$/$1/;
177
178         # Pick off direction.
179         my $dir;
180         if ($ln =~ s/^INOUT\s+//) {
181             $dir = 'INOUT';
182         } elsif ($ln =~ s/^IN\s+//) {
183             $dir = 'IN';
184         } elsif ($ln =~ s/^OUT\s+//) {
185             $dir = 'OUT';
186         } else {
187              die "No IN/OUT direction for \"$ln\".";
188         }
189         my $rele;
190         if ($ln =~ s/^WILLRELE\s+//) {
191             $rele = 'WILLRELE';
192         } else {
193             $rele = 'WONTRELE';
194         }
195
196         # kill trailing ;
197         if ($ln !~ s/;$//) {
198             die("Missing end-of-line ; in \"$ln\".");
199         }
200
201         # pick off variable name
202         if ($ln !~ s/([A-Za-z0-9_]+)$//) {
203             die("Missing var name \"a_foo\" in \"$ln\".");
204         }
205         my $arg = $1;
206
207         # what is left must be type
208         # (put clean it up some)
209         my $type = $ln;
210         # condense whitespace
211         $type =~ s/\s+/ /g;
212         $type =~ s/^\s*(.*?)\s*$/$1/;
213
214         $dirs{$numargs} = $dir;
215         $reles{$numargs} = $rele;
216         $types{$numargs} = $type;
217         $args{$numargs} = $arg;
218     }
219
220     if ($hfile) {
221         # Print out the vop_F_args structure.
222         print HEADER "struct ${name}_args {\n\tstruct vnodeop_desc *a_desc;\n";
223         for (my $c2 = 0; $c2 < $numargs; ++$c2) {
224             $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**)(\S*\;)/;
225             print HEADER "\t$3 $4a_$5\n", 
226         }
227         print HEADER "};\n";
228
229         # Print out extern declaration.
230         print HEADER "extern struct vnodeop_desc ${name}_desc;\n";
231
232         # Print out function.
233         print HEADER "static __inline int ${uname}(\n";
234         for (my $c2 = 0; $c2 < $numargs; ++$c2) {
235             $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**\S*)\;/;
236             print HEADER "\t$3 $4" .
237                 ($c2 < $numargs-1 ? "," : ")") . "\n";
238         }
239         print HEADER "{\n\tstruct ${name}_args a;\n";
240         print HEADER "\tint rc;\n";
241         print HEADER "\ta.a_desc = VDESC(${name});\n";
242         for (my $c2 = 0; $c2 < $numargs; ++$c2) {
243             $a{$c2} =~ /(\**)([^;\s]*)([^\s]*)$/;
244             print HEADER "\ta.a_$2 = $2$3\n", 
245         }
246         for (my $c2 = 0; $c2 < $numargs; ++$c2) {
247             if (!exists($args{$c2})) {
248                 die "Internal error";
249             }
250             if (exists($lockdata{$name}) &&
251                 exists($lockdata{$name}->{$args{$c2}})) {
252                 if (defined($ENV{'DEBUG_ALL_VFS_LOCKS'}) && 
253                         $ENV{'DEBUG_ALL_VFS_LOCKS'} =~ /yes/i) {
254                     # Add assertions for locking
255                     if ($lockdata{$name}->{$args{$c2}}->{Entry} eq "L") {
256                         print HEADER
257                             "\tASSERT_VOP_LOCKED($args{$c2}, \"$uname\");\n";
258                     } elsif ($lockdata{$name}->{$args{$c2}}->{Entry} eq "U") {
259                         print HEADER
260                             "\tASSERT_VOP_UNLOCKED($args{$c2}, \"$uname\");\n";
261                     } elsif (0) {
262                         # XXX More checks!
263                     }
264                 }
265             }
266         }
267         $a{0} =~ /\s\**([^;\s]*);/;
268         print HEADER "\trc = VCALL($1, VOFFSET(${name}), &a);\n";
269         print HEADER "\treturn (rc);\n";
270         print HEADER "}\n";
271     }
272
273
274     if ($cfile) {
275         # Print out the vop_F_vp_offsets structure.  This all depends
276         # on naming conventions and nothing else.
277         printf CFILE "static int %s_vp_offsets[] = {\n", $name;
278         # as a side effect, figure out the releflags
279         my $releflags = '';
280         my $vpnum = 0;
281         for (my $i = 0; $i < $numargs; $i++) {
282             if ($types{$i} eq 'struct vnode *') {
283                 printf CFILE "\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n", 
284                 $name, $args{$i};
285                 if ($reles{$i} eq 'WILLRELE') {
286                     $releflags = $releflags . '|VDESC_VP' . $vpnum . '_WILLRELE';
287                 }
288
289                 $vpnum++;
290             }
291         }
292
293         $releflags =~ s/^\|//;
294         print CFILE "\tVDESC_NO_OFFSET\n";
295         print CFILE "};\n";
296
297         # Print out the vnodeop_desc structure.
298         print CFILE "struct vnodeop_desc ${name}_desc = {\n";
299         # offset
300         print CFILE "\t0,\n";
301         # printable name
302         printf CFILE "\t\"%s\",\n", $name;
303         # flags
304         my $vppwillrele = '';
305         for (my $i = 0; $i < $numargs; $i++) {
306             if ($types{$i} eq 'struct vnode **' && 
307                 ($reles{$i} eq 'WILLRELE')) {
308                 $vppwillrele = '|VDESC_VPP_WILLRELE';
309             }
310         }
311
312         if ($releflags eq '') {
313             printf CFILE "\t0%s,\n", $vppwillrele;
314         }
315         else {
316             printf CFILE "\t%s%s,\n", $releflags, $vppwillrele;
317         }
318
319         # vp offsets
320         printf CFILE "\t%s_vp_offsets,\n", $name;
321         # vpp (if any)
322         printf CFILE "\t%s,\n", &find_arg_with_type('struct vnode **');
323         # cred (if any)
324         printf CFILE "\t%s,\n", &find_arg_with_type('struct ucred *');
325         # thread (if any)
326         printf CFILE "\t%s,\n", &find_arg_with_type('struct thread *');
327         # componentname
328         printf CFILE "\t%s,\n", &find_arg_with_type('struct componentname *');
329         # transport layer information
330         print CFILE "\tNULL,\n};\n\n";
331     }
332 }
333  
334 if ($hfile) {
335     close(HEADER) || die "Unable to close $HEADER";
336 }
337 if ($cfile) {
338     close(CFILE)  || die "Unable to close $CFILE";
339 }
340 close(SRC) || die;
341
342 exit 0;
343
344 sub find_arg_with_type {
345     my $type = shift;
346     my $i;
347
348     for ($i=0; $i < $numargs; $i++) {
349         if ($types{$i} eq $type) {
350             return "VOPARG_OFFSETOF(struct ${name}_args,a_" . $args{$i} . ")";
351         }
352     }
353
354     return "VDESC_NO_OFFSET";
355 }