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

Cache object: e0cc0875fa1eb74158588b890131e7d0


[ 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.