From 5fe01731881d033a61f612085e1ed826c2e11945 Mon Sep 17 00:00:00 2001 From: eivind Date: Sun, 26 Sep 1999 18:31:51 +0000 Subject: [PATCH] Update this to be able to output ASSERT_VOP_(UN)LOCKED() based on the lock specifications in kern/vnode_if.src. At present, this do not distinguish between exclusive and shared locks, and the kernel is so full of bugs in this area that running with auto-generation of assertions enabled makes DEBUG_VFS_LOCKS totally useless for anybody that has used it for anything prior to outputting automated assertions. Due to this, I made vnode_if.sh only output locking assertions if you have the environment variable DEBUG_ALL_VFS_LOCKS set to "YES". In order to actually use the assertions, you need to also add "options DEBUG_VFS_LOCKS" to your kernel config file. Urged to commit by: phk --- sys/kern/vnode_if.pl | 485 +++++++++++++++++++---------------------- sys/kern/vnode_if.sh | 485 +++++++++++++++++++---------------------- sys/tools/vnode_if.awk | 485 +++++++++++++++++++---------------------- 3 files changed, 690 insertions(+), 765 deletions(-) diff --git a/sys/kern/vnode_if.pl b/sys/kern/vnode_if.pl index 9c042dbac7d8..463057cc52f0 100644 --- a/sys/kern/vnode_if.pl +++ b/sys/kern/vnode_if.pl @@ -1,4 +1,7 @@ -#!/bin/sh - +#!/usr/bin/perl +eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' + if $running_under_some_shell; + # # Copyright (c) 1992, 1993 # The Regents of the University of California. All rights reserved. @@ -34,35 +37,33 @@ # @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93 # $FreeBSD$ # - # Script to produce VFS front-end sugar. # # usage: vnode_if.sh srcfile # (where srcfile is currently /sys/kern/vnode_if.src) # -# These awk scripts are not particularly well written, specifically they -# don't use arrays well and figure out the same information repeatedly. -# Please rewrite them if you actually understand how to use awk. Note, -# they use nawk extensions and gawk's toupper. -if [ $# -ne 1 ] ; then - echo 'usage: vnode_if.sh srcfile' - exit 1 -fi +my %lockdata; + + +if ($#ARGV != 0) { + print "usage: vnode_if.sh srcfile\n"; + exit(1); +} # Name of the source file. -SRC=$1 +$SRC=$ARGV[0]; # Names of the created files. -CFILE=vnode_if.c -HEADER=vnode_if.h +$CFILE='vnode_if.c'; +$HEADER='vnode_if.h'; -# Awk program (must support nawk extensions and gawk's "toupper") -# Use "awk" at Berkeley, "gawk" elsewhere. -AWK=awk +open(HEADER, ">$HEADER") || die "Unable to create $HEADER"; +open(CFILE, ">$CFILE") || die "Unable to create $CFILE"; +open(SRC, "<$SRC") || die "Unable to open input file"; # Print out header information for vnode_if.h. -cat << END_OF_LEADING_COMMENT > $HEADER +print HEADER < $HEADER extern struct vnodeop_desc vop_default_desc; END_OF_LEADING_COMMENT - -# Awk script to take vnode_if.src and turn it into vnode_if.h. -$AWK ' - NF == 0 || $0 ~ "^#" { - next; - } - { - # Get the function name. - name = $1; - uname = toupper(name); - - # Get the function arguments. - for (c1 = 0;; ++c1) { - if (getline <= 0) - exit - if ($0 ~ "^};") - break; - a[c1] = $0; - } - - # Print out the vop_F_args structure. - printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n", - name); - for (c2 = 0; c2 < c1; ++c2) { - c3 = split(a[c2], t); - printf("\t"); - if (t[2] ~ "WILLRELE") - c4 = 3; - else - c4 = 2; - for (; c4 < c3; ++c4) - printf("%s ", t[c4]); - beg = match(t[c3], "[^*]"); - printf("%sa_%s\n", - substr(t[c4], 0, beg - 1), substr(t[c4], beg)); - } - printf("};\n"); - - # Print out extern declaration. - printf("extern struct vnodeop_desc %s_desc;\n", name); - - # Print out prototype. - printf("static __inline int %s __P((\n", uname); - sep = ",\n"; - for (c2 = 0; c2 < c1; ++c2) { - if (c2 == c1 - 1) - sep = "));\n"; - c3 = split(a[c2], t); - printf("\t"); - if (t[2] ~ "WILLRELE") - c4 = 3; - else - c4 = 2; - for (; c4 < c3; ++c4) - printf("%s ", t[c4]); - beg = match(t[c3], "[^*]"); - end = match(t[c3], ";"); - printf("%s%s%s", - substr(t[c4], 0, beg - 1), - substr(t[c4], beg, end - beg), sep); - } - - # Print out function. - printf("static __inline int %s(", uname); - sep = ", "; - for (c2 = 0; c2 < c1; ++c2) { - if (c2 == c1 - 1) - sep = ")\n"; - c3 = split(a[c2], t); - beg = match(t[c3], "[^*]"); - end = match(t[c3], ";"); - printf("%s%s", substr(t[c3], beg, end - beg), sep); - } - for (c2 = 0; c2 < c1; ++c2) { - c3 = split(a[c2], t); - printf("\t"); - if (t[2] ~ "WILLRELE") - c4 = 3; - else - c4 = 2; - for (; c4 < c3; ++c4) - printf("%s ", t[c4]); - beg = match(t[c3], "[^*]"); - printf("%s%s\n", - substr(t[c4], 0, beg - 1), substr(t[c4], beg)); - } - printf("{\n\tstruct %s_args a;\n\n", name); - printf("\ta.a_desc = VDESC(%s);\n", name); - for (c2 = 0; c2 < c1; ++c2) { - c3 = split(a[c2], t); - printf("\t"); - beg = match(t[c3], "[^*]"); - end = match(t[c3], ";"); - printf("a.a_%s = %s\n", - substr(t[c3], beg, end - beg), substr(t[c3], beg)); - } - c1 = split(a[0], t); - beg = match(t[c1], "[^*]"); - end = match(t[c1], ";"); - printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n", - substr(t[c1], beg, end - beg), name); - }' < $SRC >> $HEADER + ; # Print out header information for vnode_if.c. -cat << END_OF_LEADING_COMMENT > $CFILE +print CFILE <) { + chop; # strip record separator + @Fld = split ' '; + if (@Fld == 0) { + next line; + } + if (/^#/) { + if (!/^#%\s+([a-z]+)\s+([a-z]+)\s+(.)\s(.)\s(.)/) { + next; + } + if (!defined($lockdata{"vop_$1"})) { + $lockdata{"vop_$1"} = {}; + } + $lockdata{"vop_$1"}->{$2} = { + 'Entry' => $3, + 'OK' => $4, + 'Error' => $5, + }; + next; + } + + # Get the function name. + $name = $Fld[0]; + $uname = uc($name); + + # Get the function arguments. + for ($numargs = 0; ; ++$numargs) { + if ($ln = ) { + chomp; + } else { + die "Unable to read through the arguments for \"$name\""; + } + if ($ln =~ /^\};/) { + last; + } + # For the header file + $a{$numargs} = $ln; + + # The rest of this loop is for the C file + # Delete comments, if any. + $ln =~ s/\/\*.*\*\///g; + + # Delete leading/trailing space. + $ln =~ s/^\s*(.*?)\s*$/$1/; + + # Pick off direction. + if ($ln =~ s/^INOUT\s+//) { + $dir = 'INOUT'; + } elsif ($ln =~ s/^IN\s+//) { + $dir = 'IN'; + } elsif ($ln =~ s/^OUT\s+//) { + $dir = 'OUT'; + } else { + die "No IN/OUT direction for \"$ln\"."; + } + if ($ln =~ s/^WILLRELE\s+//) { + $rele = 'WILLRELE'; + } else { + $rele = 'WONTRELE'; } - function read_args() { - numargs = 0; - while (getline ln) { - if (ln ~ /}/) { - break; - }; - - # Delete comments, if any. - gsub (/\/\*.*\*\//, "", ln); - - # Delete leading/trailing space. - ln = kill_surrounding_ws(ln); - - # Pick off direction. - if (1 == sub(/^INOUT[ \t]+/, "", ln)) - dir = "INOUT"; - else if (1 == sub(/^IN[ \t]+/, "", ln)) - dir = "IN"; - else if (1 == sub(/^OUT[ \t]+/, "", ln)) - dir = "OUT"; - else - bail("No IN/OUT direction for \"" ln "\"."); - - # check for "WILLRELE" - if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) { - rele = "WILLRELE"; - } else { - rele = "WONTRELE"; - }; - - # kill trailing ; - if (1 != sub (/;$/, "", ln)) { - bail("Missing end-of-line ; in \"" ln "\"."); - }; - - # pick off variable name - if (!(i = match(ln, /[A-Za-z0-9_]+$/))) { - bail("Missing var name \"a_foo\" in \"" ln "\"."); - }; - arg = substr (ln, i); - # Want to <>, but nawk cannot. - # Hack around this. - ln = substr(ln, 1, i-1); - - # what is left must be type - # (put clean it up some) - type = ln; - gsub (/[ \t]+/, " ", type); # condense whitespace - type = kill_surrounding_ws(type); - - # (boy this was easier in Perl) - - numargs++; - dirs[numargs] = dir; - reles[numargs] = rele; - types[numargs] = type; - args[numargs] = arg; - }; + # kill trailing ; + if ($ln !~ s/;$//) { + &bail("Missing end-of-line ; in \"$ln\"."); } - function generate_operation_vp_offsets() { - printf ("static int %s_vp_offsets[] = {\n", name); - # as a side effect, figure out the releflags - releflags = ""; - vpnum = 0; - for (i=1; i<=numargs; i++) { - if (types[i] == "struct vnode *") { - printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n", - name, args[i]); - if (reles[i] == "WILLRELE") { - releflags = releflags "|VDESC_VP" vpnum "_WILLRELE"; - }; - vpnum++; - }; - }; - sub (/^\|/, "", releflags); - print "\tVDESC_NO_OFFSET"; - print "};"; + # pick off variable name + if ($ln !~ s/([A-Za-z0-9_]+)$//) { + &bail("Missing var name \"a_foo\" in \"$ln\"."); } - - function find_arg_with_type (type) { - for (i=1; i<=numargs; i++) { - if (types[i] == type) { - return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")"; - }; - }; - return "VDESC_NO_OFFSET"; + $arg = $1; + + # what is left must be type + # (put clean it up some) + $type = $ln; + # condense whitespace + $type =~ s/\s+/ /g; + $type =~ s/^\s*(.*?)\s*$/$1/; + + $dirs{$numargs} = $dir; + $reles{$numargs} = $rele; + $types{$numargs} = $type; + $args{$numargs} = $arg; + } + + # Print out the vop_F_args structure. + print HEADER "struct ${name}_args {\n\tstruct vnodeop_desc *a_desc;\n"; + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**)(\S*\;)/; + print HEADER "\t$3 $4a_$5\n", + } + print HEADER "};\n"; + + # Print out extern declaration. + print HEADER "extern struct vnodeop_desc ${name}_desc;\n"; + + # Print out prototype. + print HEADER "static __inline int ${uname} __P((\n"; + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**\S*)\;/; + print HEADER "\t$3 $4" . + ($c2 < $numargs-1 ? "," : "));") . "\n"; + } + + # Print out function. + print HEADER "static __inline int ${uname}("; + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /\**([^;\s]*)\;[^\s]*$/; + print HEADER "$1" . ($c2 < $numargs - 1 ? ', ' : ")\n"); + } + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**\S*\;)/; + print HEADER "\t$3 $4\n"; + } + print HEADER "{\n\tstruct ${name}_args a;\n"; + print HEADER "\tint rc;\n"; + print HEADER "\ta.a_desc = VDESC(${name});\n"; + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /(\**)([^;\s]*)([^\s]*)$/; + print HEADER "\ta.a_$2 = $2$3\n", + } + for ($c2 = 0; $c2 < $numargs; ++$c2) { + if (!exists($args{$c2})) { + die "Internal error"; } - - function generate_operation_desc() { - printf ("struct vnodeop_desc %s_desc = {\n", name); - # offset - printf ("\t0,\n"); - # printable name - printf ("\t\"%s\",\n", name); - # flags - vppwillrele = ""; - for (i=1; i<=numargs; i++) { - if (types[i] == "struct vnode **" && - (reles[i] == "WILLRELE")) { - vppwillrele = "|VDESC_VPP_WILLRELE"; - }; - }; - if (releflags == "") { - printf ("\t0%s,\n", vppwillrele); - } else { - printf ("\t%s%s,\n", releflags, vppwillrele); - }; - # vp offsets - printf ("\t%s_vp_offsets,\n", name); - # vpp (if any) - printf ("\t%s,\n", find_arg_with_type("struct vnode **")); - # cred (if any) - printf ("\t%s,\n", find_arg_with_type("struct ucred *")); - # proc (if any) - printf ("\t%s,\n", find_arg_with_type("struct proc *")); - # componentname - printf ("\t%s,\n", find_arg_with_type("struct componentname *")); - # transport layer information - printf ("\tNULL,\n};\n"); + if (exists($lockdata{$name}) && + exists($lockdata{$name}->{$args{$c2}})) { + if ($ENV{'DEBUG_ALL_VFS_LOCKS'} =~ /yes/i) { + # Add assertions for locking + if ($lockdata{$name}->{$args{$c2}}->{Entry} eq "L") { + print HEADER + "\tASSERT_VOP_LOCKED($args{$c2}, \"$uname\");\n"; + } elsif ($lockdata{$name}->{$args{$c2}}->{Entry} eq "U") { + print HEADER + "\tASSERT_VOP_UNLOCKED($args{$c2}, \"$uname\");\n"; + } elsif (0) { + # XXX More checks! + } + } } + } + $a{0} =~ /\s\**([^;\s]*);/; + print HEADER "\trc = VCALL($1, VOFFSET(${name}), &a);\n"; + print HEADER "\treturn (rc);\n"; + print HEADER "}\n"; - NF == 0 || $0 ~ "^#" { - next; + + # Print out the vop_F_vp_offsets structure. This all depends + # on naming conventions and nothing else. + printf CFILE "static int %s_vp_offsets[] = {\n", $name; + # as a side effect, figure out the releflags + $releflags = ''; + $vpnum = 0; + for ($i = 0; $i < $numargs; $i++) { + if ($types{$i} eq 'struct vnode *') { + printf CFILE "\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n", + $name, $args{$i}; + if ($reles{$i} eq 'WILLRELE') { + $releflags = $releflags . '|VDESC_VP' . $vpnum . '_WILLRELE'; + } + + $vpnum++; } - { - # get the function name - name = $1; + } - # get the function arguments - read_args(); + $releflags =~ s/^\|//; + print CFILE "\tVDESC_NO_OFFSET\n"; + print CFILE "};\n"; - # Print out the vop_F_vp_offsets structure. This all depends - # on naming conventions and nothing else. - generate_operation_vp_offsets(); + # Print out the vnodeop_desc structure. + print CFILE "struct vnodeop_desc ${name}_desc = {\n"; + # offset + print CFILE "\t0,\n"; + # printable name + printf CFILE "\t\"%s\",\n", $name; + # flags + $vppwillrele = ''; + for ($i = 0; $i < $numargs; $i++) { + if ($types{$i} eq 'struct vnode **' && + ($reles{$i} eq 'WILLRELE')) { + $vppwillrele = '|VDESC_VPP_WILLRELE'; + } + } - # Print out the vnodeop_desc structure. - generate_operation_desc(); + if ($releflags eq '') { + printf CFILE "\t0%s,\n", $vppwillrele; + } + else { + printf CFILE "\t%s%s,\n", $releflags, $vppwillrele; + } - printf "\n"; + # vp offsets + printf CFILE "\t%s_vp_offsets,\n", $name; + # vpp (if any) + printf CFILE "\t%s,\n", &find_arg_with_type('struct vnode **'); + # cred (if any) + printf CFILE "\t%s,\n", &find_arg_with_type('struct ucred *'); + # proc (if any) + printf CFILE "\t%s,\n", &find_arg_with_type('struct proc *'); + # componentname + printf CFILE "\t%s,\n", &find_arg_with_type('struct componentname *'); + # transport layer information + print CFILE "\tNULL,\n};\n\n"; +} - }' < $SRC >> $CFILE +close(HEADER) || die "Unable to close $HEADER"; +close(CFILE) || die "Unable to close $CFILE"; +close(SRC) || die; + +exit 0; + +sub find_arg_with_type { + my $type = shift; + my $i; + + for ($i=0; $i < $numargs; $i++) { + if ($types{$i} eq $type) { + return "VOPARG_OFFSETOF(struct ${name}_args,a_" . $args{$i} . ")"; + } + } + + return "VDESC_NO_OFFSET"; +} diff --git a/sys/kern/vnode_if.sh b/sys/kern/vnode_if.sh index 9c042dbac7d8..463057cc52f0 100644 --- a/sys/kern/vnode_if.sh +++ b/sys/kern/vnode_if.sh @@ -1,4 +1,7 @@ -#!/bin/sh - +#!/usr/bin/perl +eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' + if $running_under_some_shell; + # # Copyright (c) 1992, 1993 # The Regents of the University of California. All rights reserved. @@ -34,35 +37,33 @@ # @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93 # $FreeBSD$ # - # Script to produce VFS front-end sugar. # # usage: vnode_if.sh srcfile # (where srcfile is currently /sys/kern/vnode_if.src) # -# These awk scripts are not particularly well written, specifically they -# don't use arrays well and figure out the same information repeatedly. -# Please rewrite them if you actually understand how to use awk. Note, -# they use nawk extensions and gawk's toupper. -if [ $# -ne 1 ] ; then - echo 'usage: vnode_if.sh srcfile' - exit 1 -fi +my %lockdata; + + +if ($#ARGV != 0) { + print "usage: vnode_if.sh srcfile\n"; + exit(1); +} # Name of the source file. -SRC=$1 +$SRC=$ARGV[0]; # Names of the created files. -CFILE=vnode_if.c -HEADER=vnode_if.h +$CFILE='vnode_if.c'; +$HEADER='vnode_if.h'; -# Awk program (must support nawk extensions and gawk's "toupper") -# Use "awk" at Berkeley, "gawk" elsewhere. -AWK=awk +open(HEADER, ">$HEADER") || die "Unable to create $HEADER"; +open(CFILE, ">$CFILE") || die "Unable to create $CFILE"; +open(SRC, "<$SRC") || die "Unable to open input file"; # Print out header information for vnode_if.h. -cat << END_OF_LEADING_COMMENT > $HEADER +print HEADER < $HEADER extern struct vnodeop_desc vop_default_desc; END_OF_LEADING_COMMENT - -# Awk script to take vnode_if.src and turn it into vnode_if.h. -$AWK ' - NF == 0 || $0 ~ "^#" { - next; - } - { - # Get the function name. - name = $1; - uname = toupper(name); - - # Get the function arguments. - for (c1 = 0;; ++c1) { - if (getline <= 0) - exit - if ($0 ~ "^};") - break; - a[c1] = $0; - } - - # Print out the vop_F_args structure. - printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n", - name); - for (c2 = 0; c2 < c1; ++c2) { - c3 = split(a[c2], t); - printf("\t"); - if (t[2] ~ "WILLRELE") - c4 = 3; - else - c4 = 2; - for (; c4 < c3; ++c4) - printf("%s ", t[c4]); - beg = match(t[c3], "[^*]"); - printf("%sa_%s\n", - substr(t[c4], 0, beg - 1), substr(t[c4], beg)); - } - printf("};\n"); - - # Print out extern declaration. - printf("extern struct vnodeop_desc %s_desc;\n", name); - - # Print out prototype. - printf("static __inline int %s __P((\n", uname); - sep = ",\n"; - for (c2 = 0; c2 < c1; ++c2) { - if (c2 == c1 - 1) - sep = "));\n"; - c3 = split(a[c2], t); - printf("\t"); - if (t[2] ~ "WILLRELE") - c4 = 3; - else - c4 = 2; - for (; c4 < c3; ++c4) - printf("%s ", t[c4]); - beg = match(t[c3], "[^*]"); - end = match(t[c3], ";"); - printf("%s%s%s", - substr(t[c4], 0, beg - 1), - substr(t[c4], beg, end - beg), sep); - } - - # Print out function. - printf("static __inline int %s(", uname); - sep = ", "; - for (c2 = 0; c2 < c1; ++c2) { - if (c2 == c1 - 1) - sep = ")\n"; - c3 = split(a[c2], t); - beg = match(t[c3], "[^*]"); - end = match(t[c3], ";"); - printf("%s%s", substr(t[c3], beg, end - beg), sep); - } - for (c2 = 0; c2 < c1; ++c2) { - c3 = split(a[c2], t); - printf("\t"); - if (t[2] ~ "WILLRELE") - c4 = 3; - else - c4 = 2; - for (; c4 < c3; ++c4) - printf("%s ", t[c4]); - beg = match(t[c3], "[^*]"); - printf("%s%s\n", - substr(t[c4], 0, beg - 1), substr(t[c4], beg)); - } - printf("{\n\tstruct %s_args a;\n\n", name); - printf("\ta.a_desc = VDESC(%s);\n", name); - for (c2 = 0; c2 < c1; ++c2) { - c3 = split(a[c2], t); - printf("\t"); - beg = match(t[c3], "[^*]"); - end = match(t[c3], ";"); - printf("a.a_%s = %s\n", - substr(t[c3], beg, end - beg), substr(t[c3], beg)); - } - c1 = split(a[0], t); - beg = match(t[c1], "[^*]"); - end = match(t[c1], ";"); - printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n", - substr(t[c1], beg, end - beg), name); - }' < $SRC >> $HEADER + ; # Print out header information for vnode_if.c. -cat << END_OF_LEADING_COMMENT > $CFILE +print CFILE <) { + chop; # strip record separator + @Fld = split ' '; + if (@Fld == 0) { + next line; + } + if (/^#/) { + if (!/^#%\s+([a-z]+)\s+([a-z]+)\s+(.)\s(.)\s(.)/) { + next; + } + if (!defined($lockdata{"vop_$1"})) { + $lockdata{"vop_$1"} = {}; + } + $lockdata{"vop_$1"}->{$2} = { + 'Entry' => $3, + 'OK' => $4, + 'Error' => $5, + }; + next; + } + + # Get the function name. + $name = $Fld[0]; + $uname = uc($name); + + # Get the function arguments. + for ($numargs = 0; ; ++$numargs) { + if ($ln = ) { + chomp; + } else { + die "Unable to read through the arguments for \"$name\""; + } + if ($ln =~ /^\};/) { + last; + } + # For the header file + $a{$numargs} = $ln; + + # The rest of this loop is for the C file + # Delete comments, if any. + $ln =~ s/\/\*.*\*\///g; + + # Delete leading/trailing space. + $ln =~ s/^\s*(.*?)\s*$/$1/; + + # Pick off direction. + if ($ln =~ s/^INOUT\s+//) { + $dir = 'INOUT'; + } elsif ($ln =~ s/^IN\s+//) { + $dir = 'IN'; + } elsif ($ln =~ s/^OUT\s+//) { + $dir = 'OUT'; + } else { + die "No IN/OUT direction for \"$ln\"."; + } + if ($ln =~ s/^WILLRELE\s+//) { + $rele = 'WILLRELE'; + } else { + $rele = 'WONTRELE'; } - function read_args() { - numargs = 0; - while (getline ln) { - if (ln ~ /}/) { - break; - }; - - # Delete comments, if any. - gsub (/\/\*.*\*\//, "", ln); - - # Delete leading/trailing space. - ln = kill_surrounding_ws(ln); - - # Pick off direction. - if (1 == sub(/^INOUT[ \t]+/, "", ln)) - dir = "INOUT"; - else if (1 == sub(/^IN[ \t]+/, "", ln)) - dir = "IN"; - else if (1 == sub(/^OUT[ \t]+/, "", ln)) - dir = "OUT"; - else - bail("No IN/OUT direction for \"" ln "\"."); - - # check for "WILLRELE" - if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) { - rele = "WILLRELE"; - } else { - rele = "WONTRELE"; - }; - - # kill trailing ; - if (1 != sub (/;$/, "", ln)) { - bail("Missing end-of-line ; in \"" ln "\"."); - }; - - # pick off variable name - if (!(i = match(ln, /[A-Za-z0-9_]+$/))) { - bail("Missing var name \"a_foo\" in \"" ln "\"."); - }; - arg = substr (ln, i); - # Want to <>, but nawk cannot. - # Hack around this. - ln = substr(ln, 1, i-1); - - # what is left must be type - # (put clean it up some) - type = ln; - gsub (/[ \t]+/, " ", type); # condense whitespace - type = kill_surrounding_ws(type); - - # (boy this was easier in Perl) - - numargs++; - dirs[numargs] = dir; - reles[numargs] = rele; - types[numargs] = type; - args[numargs] = arg; - }; + # kill trailing ; + if ($ln !~ s/;$//) { + &bail("Missing end-of-line ; in \"$ln\"."); } - function generate_operation_vp_offsets() { - printf ("static int %s_vp_offsets[] = {\n", name); - # as a side effect, figure out the releflags - releflags = ""; - vpnum = 0; - for (i=1; i<=numargs; i++) { - if (types[i] == "struct vnode *") { - printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n", - name, args[i]); - if (reles[i] == "WILLRELE") { - releflags = releflags "|VDESC_VP" vpnum "_WILLRELE"; - }; - vpnum++; - }; - }; - sub (/^\|/, "", releflags); - print "\tVDESC_NO_OFFSET"; - print "};"; + # pick off variable name + if ($ln !~ s/([A-Za-z0-9_]+)$//) { + &bail("Missing var name \"a_foo\" in \"$ln\"."); } - - function find_arg_with_type (type) { - for (i=1; i<=numargs; i++) { - if (types[i] == type) { - return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")"; - }; - }; - return "VDESC_NO_OFFSET"; + $arg = $1; + + # what is left must be type + # (put clean it up some) + $type = $ln; + # condense whitespace + $type =~ s/\s+/ /g; + $type =~ s/^\s*(.*?)\s*$/$1/; + + $dirs{$numargs} = $dir; + $reles{$numargs} = $rele; + $types{$numargs} = $type; + $args{$numargs} = $arg; + } + + # Print out the vop_F_args structure. + print HEADER "struct ${name}_args {\n\tstruct vnodeop_desc *a_desc;\n"; + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**)(\S*\;)/; + print HEADER "\t$3 $4a_$5\n", + } + print HEADER "};\n"; + + # Print out extern declaration. + print HEADER "extern struct vnodeop_desc ${name}_desc;\n"; + + # Print out prototype. + print HEADER "static __inline int ${uname} __P((\n"; + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**\S*)\;/; + print HEADER "\t$3 $4" . + ($c2 < $numargs-1 ? "," : "));") . "\n"; + } + + # Print out function. + print HEADER "static __inline int ${uname}("; + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /\**([^;\s]*)\;[^\s]*$/; + print HEADER "$1" . ($c2 < $numargs - 1 ? ', ' : ")\n"); + } + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**\S*\;)/; + print HEADER "\t$3 $4\n"; + } + print HEADER "{\n\tstruct ${name}_args a;\n"; + print HEADER "\tint rc;\n"; + print HEADER "\ta.a_desc = VDESC(${name});\n"; + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /(\**)([^;\s]*)([^\s]*)$/; + print HEADER "\ta.a_$2 = $2$3\n", + } + for ($c2 = 0; $c2 < $numargs; ++$c2) { + if (!exists($args{$c2})) { + die "Internal error"; } - - function generate_operation_desc() { - printf ("struct vnodeop_desc %s_desc = {\n", name); - # offset - printf ("\t0,\n"); - # printable name - printf ("\t\"%s\",\n", name); - # flags - vppwillrele = ""; - for (i=1; i<=numargs; i++) { - if (types[i] == "struct vnode **" && - (reles[i] == "WILLRELE")) { - vppwillrele = "|VDESC_VPP_WILLRELE"; - }; - }; - if (releflags == "") { - printf ("\t0%s,\n", vppwillrele); - } else { - printf ("\t%s%s,\n", releflags, vppwillrele); - }; - # vp offsets - printf ("\t%s_vp_offsets,\n", name); - # vpp (if any) - printf ("\t%s,\n", find_arg_with_type("struct vnode **")); - # cred (if any) - printf ("\t%s,\n", find_arg_with_type("struct ucred *")); - # proc (if any) - printf ("\t%s,\n", find_arg_with_type("struct proc *")); - # componentname - printf ("\t%s,\n", find_arg_with_type("struct componentname *")); - # transport layer information - printf ("\tNULL,\n};\n"); + if (exists($lockdata{$name}) && + exists($lockdata{$name}->{$args{$c2}})) { + if ($ENV{'DEBUG_ALL_VFS_LOCKS'} =~ /yes/i) { + # Add assertions for locking + if ($lockdata{$name}->{$args{$c2}}->{Entry} eq "L") { + print HEADER + "\tASSERT_VOP_LOCKED($args{$c2}, \"$uname\");\n"; + } elsif ($lockdata{$name}->{$args{$c2}}->{Entry} eq "U") { + print HEADER + "\tASSERT_VOP_UNLOCKED($args{$c2}, \"$uname\");\n"; + } elsif (0) { + # XXX More checks! + } + } } + } + $a{0} =~ /\s\**([^;\s]*);/; + print HEADER "\trc = VCALL($1, VOFFSET(${name}), &a);\n"; + print HEADER "\treturn (rc);\n"; + print HEADER "}\n"; - NF == 0 || $0 ~ "^#" { - next; + + # Print out the vop_F_vp_offsets structure. This all depends + # on naming conventions and nothing else. + printf CFILE "static int %s_vp_offsets[] = {\n", $name; + # as a side effect, figure out the releflags + $releflags = ''; + $vpnum = 0; + for ($i = 0; $i < $numargs; $i++) { + if ($types{$i} eq 'struct vnode *') { + printf CFILE "\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n", + $name, $args{$i}; + if ($reles{$i} eq 'WILLRELE') { + $releflags = $releflags . '|VDESC_VP' . $vpnum . '_WILLRELE'; + } + + $vpnum++; } - { - # get the function name - name = $1; + } - # get the function arguments - read_args(); + $releflags =~ s/^\|//; + print CFILE "\tVDESC_NO_OFFSET\n"; + print CFILE "};\n"; - # Print out the vop_F_vp_offsets structure. This all depends - # on naming conventions and nothing else. - generate_operation_vp_offsets(); + # Print out the vnodeop_desc structure. + print CFILE "struct vnodeop_desc ${name}_desc = {\n"; + # offset + print CFILE "\t0,\n"; + # printable name + printf CFILE "\t\"%s\",\n", $name; + # flags + $vppwillrele = ''; + for ($i = 0; $i < $numargs; $i++) { + if ($types{$i} eq 'struct vnode **' && + ($reles{$i} eq 'WILLRELE')) { + $vppwillrele = '|VDESC_VPP_WILLRELE'; + } + } - # Print out the vnodeop_desc structure. - generate_operation_desc(); + if ($releflags eq '') { + printf CFILE "\t0%s,\n", $vppwillrele; + } + else { + printf CFILE "\t%s%s,\n", $releflags, $vppwillrele; + } - printf "\n"; + # vp offsets + printf CFILE "\t%s_vp_offsets,\n", $name; + # vpp (if any) + printf CFILE "\t%s,\n", &find_arg_with_type('struct vnode **'); + # cred (if any) + printf CFILE "\t%s,\n", &find_arg_with_type('struct ucred *'); + # proc (if any) + printf CFILE "\t%s,\n", &find_arg_with_type('struct proc *'); + # componentname + printf CFILE "\t%s,\n", &find_arg_with_type('struct componentname *'); + # transport layer information + print CFILE "\tNULL,\n};\n\n"; +} - }' < $SRC >> $CFILE +close(HEADER) || die "Unable to close $HEADER"; +close(CFILE) || die "Unable to close $CFILE"; +close(SRC) || die; + +exit 0; + +sub find_arg_with_type { + my $type = shift; + my $i; + + for ($i=0; $i < $numargs; $i++) { + if ($types{$i} eq $type) { + return "VOPARG_OFFSETOF(struct ${name}_args,a_" . $args{$i} . ")"; + } + } + + return "VDESC_NO_OFFSET"; +} diff --git a/sys/tools/vnode_if.awk b/sys/tools/vnode_if.awk index 9c042dbac7d8..463057cc52f0 100644 --- a/sys/tools/vnode_if.awk +++ b/sys/tools/vnode_if.awk @@ -1,4 +1,7 @@ -#!/bin/sh - +#!/usr/bin/perl +eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' + if $running_under_some_shell; + # # Copyright (c) 1992, 1993 # The Regents of the University of California. All rights reserved. @@ -34,35 +37,33 @@ # @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93 # $FreeBSD$ # - # Script to produce VFS front-end sugar. # # usage: vnode_if.sh srcfile # (where srcfile is currently /sys/kern/vnode_if.src) # -# These awk scripts are not particularly well written, specifically they -# don't use arrays well and figure out the same information repeatedly. -# Please rewrite them if you actually understand how to use awk. Note, -# they use nawk extensions and gawk's toupper. -if [ $# -ne 1 ] ; then - echo 'usage: vnode_if.sh srcfile' - exit 1 -fi +my %lockdata; + + +if ($#ARGV != 0) { + print "usage: vnode_if.sh srcfile\n"; + exit(1); +} # Name of the source file. -SRC=$1 +$SRC=$ARGV[0]; # Names of the created files. -CFILE=vnode_if.c -HEADER=vnode_if.h +$CFILE='vnode_if.c'; +$HEADER='vnode_if.h'; -# Awk program (must support nawk extensions and gawk's "toupper") -# Use "awk" at Berkeley, "gawk" elsewhere. -AWK=awk +open(HEADER, ">$HEADER") || die "Unable to create $HEADER"; +open(CFILE, ">$CFILE") || die "Unable to create $CFILE"; +open(SRC, "<$SRC") || die "Unable to open input file"; # Print out header information for vnode_if.h. -cat << END_OF_LEADING_COMMENT > $HEADER +print HEADER < $HEADER extern struct vnodeop_desc vop_default_desc; END_OF_LEADING_COMMENT - -# Awk script to take vnode_if.src and turn it into vnode_if.h. -$AWK ' - NF == 0 || $0 ~ "^#" { - next; - } - { - # Get the function name. - name = $1; - uname = toupper(name); - - # Get the function arguments. - for (c1 = 0;; ++c1) { - if (getline <= 0) - exit - if ($0 ~ "^};") - break; - a[c1] = $0; - } - - # Print out the vop_F_args structure. - printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n", - name); - for (c2 = 0; c2 < c1; ++c2) { - c3 = split(a[c2], t); - printf("\t"); - if (t[2] ~ "WILLRELE") - c4 = 3; - else - c4 = 2; - for (; c4 < c3; ++c4) - printf("%s ", t[c4]); - beg = match(t[c3], "[^*]"); - printf("%sa_%s\n", - substr(t[c4], 0, beg - 1), substr(t[c4], beg)); - } - printf("};\n"); - - # Print out extern declaration. - printf("extern struct vnodeop_desc %s_desc;\n", name); - - # Print out prototype. - printf("static __inline int %s __P((\n", uname); - sep = ",\n"; - for (c2 = 0; c2 < c1; ++c2) { - if (c2 == c1 - 1) - sep = "));\n"; - c3 = split(a[c2], t); - printf("\t"); - if (t[2] ~ "WILLRELE") - c4 = 3; - else - c4 = 2; - for (; c4 < c3; ++c4) - printf("%s ", t[c4]); - beg = match(t[c3], "[^*]"); - end = match(t[c3], ";"); - printf("%s%s%s", - substr(t[c4], 0, beg - 1), - substr(t[c4], beg, end - beg), sep); - } - - # Print out function. - printf("static __inline int %s(", uname); - sep = ", "; - for (c2 = 0; c2 < c1; ++c2) { - if (c2 == c1 - 1) - sep = ")\n"; - c3 = split(a[c2], t); - beg = match(t[c3], "[^*]"); - end = match(t[c3], ";"); - printf("%s%s", substr(t[c3], beg, end - beg), sep); - } - for (c2 = 0; c2 < c1; ++c2) { - c3 = split(a[c2], t); - printf("\t"); - if (t[2] ~ "WILLRELE") - c4 = 3; - else - c4 = 2; - for (; c4 < c3; ++c4) - printf("%s ", t[c4]); - beg = match(t[c3], "[^*]"); - printf("%s%s\n", - substr(t[c4], 0, beg - 1), substr(t[c4], beg)); - } - printf("{\n\tstruct %s_args a;\n\n", name); - printf("\ta.a_desc = VDESC(%s);\n", name); - for (c2 = 0; c2 < c1; ++c2) { - c3 = split(a[c2], t); - printf("\t"); - beg = match(t[c3], "[^*]"); - end = match(t[c3], ";"); - printf("a.a_%s = %s\n", - substr(t[c3], beg, end - beg), substr(t[c3], beg)); - } - c1 = split(a[0], t); - beg = match(t[c1], "[^*]"); - end = match(t[c1], ";"); - printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n", - substr(t[c1], beg, end - beg), name); - }' < $SRC >> $HEADER + ; # Print out header information for vnode_if.c. -cat << END_OF_LEADING_COMMENT > $CFILE +print CFILE <) { + chop; # strip record separator + @Fld = split ' '; + if (@Fld == 0) { + next line; + } + if (/^#/) { + if (!/^#%\s+([a-z]+)\s+([a-z]+)\s+(.)\s(.)\s(.)/) { + next; + } + if (!defined($lockdata{"vop_$1"})) { + $lockdata{"vop_$1"} = {}; + } + $lockdata{"vop_$1"}->{$2} = { + 'Entry' => $3, + 'OK' => $4, + 'Error' => $5, + }; + next; + } + + # Get the function name. + $name = $Fld[0]; + $uname = uc($name); + + # Get the function arguments. + for ($numargs = 0; ; ++$numargs) { + if ($ln = ) { + chomp; + } else { + die "Unable to read through the arguments for \"$name\""; + } + if ($ln =~ /^\};/) { + last; + } + # For the header file + $a{$numargs} = $ln; + + # The rest of this loop is for the C file + # Delete comments, if any. + $ln =~ s/\/\*.*\*\///g; + + # Delete leading/trailing space. + $ln =~ s/^\s*(.*?)\s*$/$1/; + + # Pick off direction. + if ($ln =~ s/^INOUT\s+//) { + $dir = 'INOUT'; + } elsif ($ln =~ s/^IN\s+//) { + $dir = 'IN'; + } elsif ($ln =~ s/^OUT\s+//) { + $dir = 'OUT'; + } else { + die "No IN/OUT direction for \"$ln\"."; + } + if ($ln =~ s/^WILLRELE\s+//) { + $rele = 'WILLRELE'; + } else { + $rele = 'WONTRELE'; } - function read_args() { - numargs = 0; - while (getline ln) { - if (ln ~ /}/) { - break; - }; - - # Delete comments, if any. - gsub (/\/\*.*\*\//, "", ln); - - # Delete leading/trailing space. - ln = kill_surrounding_ws(ln); - - # Pick off direction. - if (1 == sub(/^INOUT[ \t]+/, "", ln)) - dir = "INOUT"; - else if (1 == sub(/^IN[ \t]+/, "", ln)) - dir = "IN"; - else if (1 == sub(/^OUT[ \t]+/, "", ln)) - dir = "OUT"; - else - bail("No IN/OUT direction for \"" ln "\"."); - - # check for "WILLRELE" - if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) { - rele = "WILLRELE"; - } else { - rele = "WONTRELE"; - }; - - # kill trailing ; - if (1 != sub (/;$/, "", ln)) { - bail("Missing end-of-line ; in \"" ln "\"."); - }; - - # pick off variable name - if (!(i = match(ln, /[A-Za-z0-9_]+$/))) { - bail("Missing var name \"a_foo\" in \"" ln "\"."); - }; - arg = substr (ln, i); - # Want to <>, but nawk cannot. - # Hack around this. - ln = substr(ln, 1, i-1); - - # what is left must be type - # (put clean it up some) - type = ln; - gsub (/[ \t]+/, " ", type); # condense whitespace - type = kill_surrounding_ws(type); - - # (boy this was easier in Perl) - - numargs++; - dirs[numargs] = dir; - reles[numargs] = rele; - types[numargs] = type; - args[numargs] = arg; - }; + # kill trailing ; + if ($ln !~ s/;$//) { + &bail("Missing end-of-line ; in \"$ln\"."); } - function generate_operation_vp_offsets() { - printf ("static int %s_vp_offsets[] = {\n", name); - # as a side effect, figure out the releflags - releflags = ""; - vpnum = 0; - for (i=1; i<=numargs; i++) { - if (types[i] == "struct vnode *") { - printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n", - name, args[i]); - if (reles[i] == "WILLRELE") { - releflags = releflags "|VDESC_VP" vpnum "_WILLRELE"; - }; - vpnum++; - }; - }; - sub (/^\|/, "", releflags); - print "\tVDESC_NO_OFFSET"; - print "};"; + # pick off variable name + if ($ln !~ s/([A-Za-z0-9_]+)$//) { + &bail("Missing var name \"a_foo\" in \"$ln\"."); } - - function find_arg_with_type (type) { - for (i=1; i<=numargs; i++) { - if (types[i] == type) { - return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")"; - }; - }; - return "VDESC_NO_OFFSET"; + $arg = $1; + + # what is left must be type + # (put clean it up some) + $type = $ln; + # condense whitespace + $type =~ s/\s+/ /g; + $type =~ s/^\s*(.*?)\s*$/$1/; + + $dirs{$numargs} = $dir; + $reles{$numargs} = $rele; + $types{$numargs} = $type; + $args{$numargs} = $arg; + } + + # Print out the vop_F_args structure. + print HEADER "struct ${name}_args {\n\tstruct vnodeop_desc *a_desc;\n"; + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**)(\S*\;)/; + print HEADER "\t$3 $4a_$5\n", + } + print HEADER "};\n"; + + # Print out extern declaration. + print HEADER "extern struct vnodeop_desc ${name}_desc;\n"; + + # Print out prototype. + print HEADER "static __inline int ${uname} __P((\n"; + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**\S*)\;/; + print HEADER "\t$3 $4" . + ($c2 < $numargs-1 ? "," : "));") . "\n"; + } + + # Print out function. + print HEADER "static __inline int ${uname}("; + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /\**([^;\s]*)\;[^\s]*$/; + print HEADER "$1" . ($c2 < $numargs - 1 ? ', ' : ")\n"); + } + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**\S*\;)/; + print HEADER "\t$3 $4\n"; + } + print HEADER "{\n\tstruct ${name}_args a;\n"; + print HEADER "\tint rc;\n"; + print HEADER "\ta.a_desc = VDESC(${name});\n"; + for ($c2 = 0; $c2 < $numargs; ++$c2) { + $a{$c2} =~ /(\**)([^;\s]*)([^\s]*)$/; + print HEADER "\ta.a_$2 = $2$3\n", + } + for ($c2 = 0; $c2 < $numargs; ++$c2) { + if (!exists($args{$c2})) { + die "Internal error"; } - - function generate_operation_desc() { - printf ("struct vnodeop_desc %s_desc = {\n", name); - # offset - printf ("\t0,\n"); - # printable name - printf ("\t\"%s\",\n", name); - # flags - vppwillrele = ""; - for (i=1; i<=numargs; i++) { - if (types[i] == "struct vnode **" && - (reles[i] == "WILLRELE")) { - vppwillrele = "|VDESC_VPP_WILLRELE"; - }; - }; - if (releflags == "") { - printf ("\t0%s,\n", vppwillrele); - } else { - printf ("\t%s%s,\n", releflags, vppwillrele); - }; - # vp offsets - printf ("\t%s_vp_offsets,\n", name); - # vpp (if any) - printf ("\t%s,\n", find_arg_with_type("struct vnode **")); - # cred (if any) - printf ("\t%s,\n", find_arg_with_type("struct ucred *")); - # proc (if any) - printf ("\t%s,\n", find_arg_with_type("struct proc *")); - # componentname - printf ("\t%s,\n", find_arg_with_type("struct componentname *")); - # transport layer information - printf ("\tNULL,\n};\n"); + if (exists($lockdata{$name}) && + exists($lockdata{$name}->{$args{$c2}})) { + if ($ENV{'DEBUG_ALL_VFS_LOCKS'} =~ /yes/i) { + # Add assertions for locking + if ($lockdata{$name}->{$args{$c2}}->{Entry} eq "L") { + print HEADER + "\tASSERT_VOP_LOCKED($args{$c2}, \"$uname\");\n"; + } elsif ($lockdata{$name}->{$args{$c2}}->{Entry} eq "U") { + print HEADER + "\tASSERT_VOP_UNLOCKED($args{$c2}, \"$uname\");\n"; + } elsif (0) { + # XXX More checks! + } + } } + } + $a{0} =~ /\s\**([^;\s]*);/; + print HEADER "\trc = VCALL($1, VOFFSET(${name}), &a);\n"; + print HEADER "\treturn (rc);\n"; + print HEADER "}\n"; - NF == 0 || $0 ~ "^#" { - next; + + # Print out the vop_F_vp_offsets structure. This all depends + # on naming conventions and nothing else. + printf CFILE "static int %s_vp_offsets[] = {\n", $name; + # as a side effect, figure out the releflags + $releflags = ''; + $vpnum = 0; + for ($i = 0; $i < $numargs; $i++) { + if ($types{$i} eq 'struct vnode *') { + printf CFILE "\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n", + $name, $args{$i}; + if ($reles{$i} eq 'WILLRELE') { + $releflags = $releflags . '|VDESC_VP' . $vpnum . '_WILLRELE'; + } + + $vpnum++; } - { - # get the function name - name = $1; + } - # get the function arguments - read_args(); + $releflags =~ s/^\|//; + print CFILE "\tVDESC_NO_OFFSET\n"; + print CFILE "};\n"; - # Print out the vop_F_vp_offsets structure. This all depends - # on naming conventions and nothing else. - generate_operation_vp_offsets(); + # Print out the vnodeop_desc structure. + print CFILE "struct vnodeop_desc ${name}_desc = {\n"; + # offset + print CFILE "\t0,\n"; + # printable name + printf CFILE "\t\"%s\",\n", $name; + # flags + $vppwillrele = ''; + for ($i = 0; $i < $numargs; $i++) { + if ($types{$i} eq 'struct vnode **' && + ($reles{$i} eq 'WILLRELE')) { + $vppwillrele = '|VDESC_VPP_WILLRELE'; + } + } - # Print out the vnodeop_desc structure. - generate_operation_desc(); + if ($releflags eq '') { + printf CFILE "\t0%s,\n", $vppwillrele; + } + else { + printf CFILE "\t%s%s,\n", $releflags, $vppwillrele; + } - printf "\n"; + # vp offsets + printf CFILE "\t%s_vp_offsets,\n", $name; + # vpp (if any) + printf CFILE "\t%s,\n", &find_arg_with_type('struct vnode **'); + # cred (if any) + printf CFILE "\t%s,\n", &find_arg_with_type('struct ucred *'); + # proc (if any) + printf CFILE "\t%s,\n", &find_arg_with_type('struct proc *'); + # componentname + printf CFILE "\t%s,\n", &find_arg_with_type('struct componentname *'); + # transport layer information + print CFILE "\tNULL,\n};\n\n"; +} - }' < $SRC >> $CFILE +close(HEADER) || die "Unable to close $HEADER"; +close(CFILE) || die "Unable to close $CFILE"; +close(SRC) || die; + +exit 0; + +sub find_arg_with_type { + my $type = shift; + my $i; + + for ($i=0; $i < $numargs; $i++) { + if ($types{$i} eq $type) { + return "VOPARG_OFFSETOF(struct ${name}_args,a_" . $args{$i} . ")"; + } + } + + return "VDESC_NO_OFFSET"; +}