The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/vnode_if.sh

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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.43 2006/11/30 21:06:29 pooka 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 
  107         if ($2 == "LOCKED=YES") {
  108                 lockstate[argc] = 1;
  109                 i++;
  110         } else if ($2 == "LOCKED=NO") {
  111                 lockstate[argc] = 0;
  112                 i++;
  113         } else
  114                 lockstate[argc] = -1;
  115 
  116         if ($2 == "WILLRELE" ||
  117             $3 == "WILLRELE") {
  118                 willrele[argc] = 1;
  119                 i++;
  120         } else if ($2 == "WILLUNLOCK" ||
  121                    $3 == "WILLUNLOCK") {
  122                 willrele[argc] = 2;
  123                 i++;
  124         } else if ($2 == "WILLPUT" ||
  125                    $3 == "WILLPUT") {
  126                 willrele[argc] = 3;
  127                 i++;
  128         } else
  129                 willrele[argc] = 0;
  130         argtype[argc] = $i; i++;
  131         while (i < NF) {
  132                 argtype[argc] = argtype[argc]" "$i;
  133                 i++;
  134         }
  135         argname[argc] = $i;
  136         argc++;
  137         next;
  138 }
  139 '
  140 
  141 # This is put before the copyright on each generated file.
  142 warning="\
  143 /*      @NetBSD@        */
  144 
  145 /*
  146  * Warning: DO NOT EDIT! This file is automatically generated!
  147  * (Modifications made here may easily be lost!)
  148  *
  149  * Created from the file:
  150  *      ${SRC_ID}
  151  * by the script:
  152  *      ${SCRIPT_ID}
  153  */
  154 "
  155 
  156 # This is to satisfy McKusick (get rid of evil spaces 8^)
  157 anal_retentive='s:\([^/]\*\) :\1:g'
  158 
  159 #
  160 # Redirect stdout to the H file.
  161 #
  162 echo "$0: Creating $out_h" 1>&2
  163 exec > $out_h
  164 
  165 # Begin stuff
  166 echo -n "$warning" | sed -e 's/\$//g;s/@/\$/g;s/ $//'
  167 echo ""
  168 echo -n "$copyright"
  169 echo ''
  170 echo '#ifndef _SYS_VNODE_IF_H_'
  171 echo '#define _SYS_VNODE_IF_H_'
  172 echo ''
  173 echo '#ifdef _KERNEL_OPT'
  174 echo '#include "opt_vnode_lockdebug.h"'
  175 echo '#endif /* _KERNEL_OPT */'
  176 echo '
  177 extern const struct vnodeop_desc vop_default_desc;
  178 '
  179 
  180 # Body stuff
  181 # This awk program needs toupper() so define it if necessary.
  182 sed -e "$sed_prep" $src | $awk "$toupper"'
  183 function doit() {
  184         # Declare arg struct, descriptor.
  185         printf("\n#define %s_DESCOFFSET %d\n", toupper(name), vop_offset++);
  186         printf("struct %s_args {\n", name);
  187         printf("\tconst struct vnodeop_desc * a_desc;\n");
  188         for (i=0; i<argc; i++) {
  189                 printf("\t%s a_%s;\n", argtype[i], argname[i]);
  190         }
  191         printf("};\n");
  192         printf("extern const struct vnodeop_desc %s_desc;\n", name);
  193         # Prototype it.
  194         protoarg = sprintf("int %s(", toupper(name));
  195         protolen = length(protoarg);
  196         printf("%s", protoarg);
  197         for (i=0; i<argc; i++) {
  198                 protoarg = sprintf("%s", argtype[i]);
  199                 if (i < (argc-1)) protoarg = (protoarg ", ");
  200                 arglen = length(protoarg);
  201                 if ((protolen + arglen) > 77) {
  202                         protoarg = ("\n    " protoarg);
  203                         arglen += 4;
  204                         protolen = 0;
  205                 }
  206                 printf("%s", protoarg);
  207                 protolen += arglen;
  208         }
  209         printf(");\n");
  210 }
  211 BEGIN   {
  212         arg0special="";
  213         vop_offset = 1; # start at 1, to count the 'default' op
  214 
  215         printf("\n/* Special cases: */\n#include <sys/buf.h>\n");
  216         argc=1;
  217         argtype[0]="struct buf *";
  218         argname[0]="bp";
  219         lockstate[0] = -1;
  220         arg0special="->b_vp";
  221         name="vop_bwrite";
  222         doit();
  223         printf("/* End of special cases */\n");
  224 }
  225 END     {
  226         printf("\n#define VNODE_OPS_COUNT\t%d\n", vop_offset);
  227 }
  228 '"$awk_parser" | sed -e "$anal_retentive"
  229 
  230 # End stuff
  231 echo '
  232 /* End of special cases. */'
  233 echo ''
  234 echo '#endif /* !_SYS_VNODE_IF_H_ */'
  235 
  236 #
  237 # Redirect stdout to the C file.
  238 #
  239 echo "$0: Creating $out_c" 1>&2
  240 exec > $out_c
  241 
  242 # Begin stuff
  243 echo -n "$warning" | sed -e 's/\$//g;s/@/\$/g;s/ $//'
  244 echo ""
  245 echo -n "$copyright"
  246 echo "
  247 #include <sys/cdefs.h>
  248 __KERNEL_RCSID(0, \"\$NetBSD\$\");
  249 "
  250 
  251 echo '
  252 /*
  253  * If we have LKM support, always include the non-inline versions for
  254  * LKMs.  Otherwise, do it based on the option.
  255  */
  256 #include "opt_vnode_lockdebug.h"'
  257 echo '
  258 #include <sys/param.h>
  259 #include <sys/mount.h>
  260 #include <sys/buf.h>
  261 #include <sys/vnode.h>
  262 
  263 const struct vnodeop_desc vop_default_desc = {
  264         0,
  265         "default",
  266         0,
  267         NULL,
  268         VDESC_NO_OFFSET,
  269         VDESC_NO_OFFSET,
  270         VDESC_NO_OFFSET,
  271         VDESC_NO_OFFSET,
  272         NULL,
  273 };
  274 '
  275 
  276 # Body stuff
  277 sed -e "$sed_prep" $src | $awk '
  278 function do_offset(typematch) {
  279         for (i=0; i<argc; i++) {
  280                 if (argtype[i] == typematch) {
  281                         printf("\tVOPARG_OFFSETOF(struct %s_args, a_%s),\n",
  282                                 name, argname[i]);
  283                         return i;
  284                 };
  285         };
  286         print "\tVDESC_NO_OFFSET,";
  287         return -1;
  288 }
  289 
  290 function doit() {
  291         # Define offsets array
  292         printf("\nconst int %s_vp_offsets[] = {\n", name);
  293         for (i=0; i<argc; i++) {
  294                 if (argtype[i] == "struct vnode *") {
  295                         printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
  296                                 name, argname[i]);
  297                 }
  298         }
  299         print "\tVDESC_NO_OFFSET";
  300         print "};";
  301         # Define F_desc
  302         printf("const struct vnodeop_desc %s_desc = {\n", name);
  303         # offset
  304         printf ("\t%s_DESCOFFSET,\n", toupper(name));
  305         # printable name
  306         printf ("\t\"%s\",\n", name);
  307         # flags
  308         printf("\t0");
  309         vpnum = 0;
  310         for (i=0; i<argc; i++) {
  311                 if (willrele[i]) {
  312                         if (willrele[i] == 2) {
  313                                 word = "UNLOCK";
  314                         } else if (willrele[i] == 3) {
  315                                 word = "PUT";
  316                         } else {
  317                                 word = "RELE";
  318                         }
  319                         if (argdir[i] ~ /OUT/) {
  320                                 printf(" | VDESC_VPP_WILL%s", word);
  321                         } else {
  322                                 printf(" | VDESC_VP%s_WILL%s", vpnum, word);
  323                         };
  324                         vpnum++;
  325                 }
  326         }
  327         print ",";
  328         # vp offsets
  329         printf ("\t%s_vp_offsets,\n", name);
  330         # vpp (if any)
  331         do_offset("struct vnode **");
  332         # cred (if any)
  333         do_offset("kauth_cred_t");
  334         # lwp (if any)
  335         do_offset("struct lwp *");
  336         # componentname
  337         do_offset("struct componentname *");
  338         # transport layer information
  339         printf ("\tNULL,\n};\n");
  340 
  341         # Define function.
  342         printf("int\n%s(", toupper(name));
  343         for (i=0; i<argc; i++) {
  344                 printf("%s %s", argtype[i], argname[i]);
  345                 if (i < (argc-1)) printf(",\n    ");
  346         }
  347         printf(")\n");
  348         printf("{\n\tstruct %s_args a;\n", name);
  349         printf("#ifdef VNODE_LOCKDEBUG\n");
  350         for (i=0; i<argc; i++) {
  351                 if (lockstate[i] != -1)
  352                         printf("\tint islocked_%s;\n", argname[i]);
  353         }
  354         printf("#endif\n");
  355         printf("\ta.a_desc = VDESC(%s);\n", name);
  356         for (i=0; i<argc; i++) {
  357                 printf("\ta.a_%s = %s;\n", argname[i], argname[i]);
  358                 if (lockstate[i] != -1) {
  359                         printf("#ifdef VNODE_LOCKDEBUG\n");
  360                         printf("\tislocked_%s = (%s->v_flag & VLOCKSWORK) ? (VOP_ISLOCKED(%s) == LK_EXCLUSIVE) : %d;\n",
  361                             argname[i], argname[i], argname[i], lockstate[i]);
  362                         printf("\tif (islocked_%s != %d)\n", argname[i],
  363                             lockstate[i]);
  364                         printf("\t\tpanic(\"%s: %s: locked %%d, expected %%d\", islocked_%s, %d);\n", name, argname[i], argname[i], lockstate[i]);
  365                         printf("#endif\n");
  366                 }
  367         }
  368         printf("\treturn (VCALL(%s%s, VOFFSET(%s), &a));\n}\n",
  369                 argname[0], arg0special, name);
  370 }
  371 BEGIN   {
  372         printf("\n/* Special cases: */\n");
  373         # start from 1 (vop_default is at 0)
  374         argc=1;
  375         argdir[0]="IN";
  376         argtype[0]="struct buf *";
  377         argname[0]="bp";
  378         lockstate[0] = -1;
  379         arg0special="->b_vp";
  380         willrele[0]=0;
  381         name="vop_bwrite";
  382         doit();
  383         printf("\n/* End of special cases */\n");
  384 
  385         arg0special="";
  386 }
  387 '"$awk_parser" | sed -e "$anal_retentive"
  388 
  389 # End stuff
  390 echo '
  391 /* End of special cases. */'
  392 
  393 # Add the vfs_op_descs array to the C file.
  394 # Begin stuff
  395 echo '
  396 const struct vnodeop_desc * const vfs_op_descs[] = {
  397         &vop_default_desc,      /* MUST BE FIRST */
  398         &vop_bwrite_desc,       /* XXX: SPECIAL CASE */
  399 '
  400 
  401 # Body stuff
  402 sed -e "$sed_prep" $src | $awk '
  403 function doit() {
  404         printf("\t&%s_desc,\n", name);
  405 }
  406 '"$awk_parser"
  407 
  408 # End stuff
  409 echo '  NULL
  410 };
  411 '
  412 
  413 exit 0
  414 
  415 # Local Variables:
  416 # tab-width: 4
  417 # End:

Cache object: 462011370c913dbff696a9ffe89573f7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.