vnode_if.awk revision 1541
11541Srgrimes#!/bin/sh - 21541Srgrimes# 31541Srgrimes# Copyright (c) 1992, 1993 41541Srgrimes# The Regents of the University of California. All rights reserved. 51541Srgrimes# 61541Srgrimes# Redistribution and use in source and binary forms, with or without 71541Srgrimes# modification, are permitted provided that the following conditions 81541Srgrimes# are met: 91541Srgrimes# 1. Redistributions of source code must retain the above copyright 101541Srgrimes# notice, this list of conditions and the following disclaimer. 111541Srgrimes# 2. Redistributions in binary form must reproduce the above copyright 121541Srgrimes# notice, this list of conditions and the following disclaimer in the 131541Srgrimes# documentation and/or other materials provided with the distribution. 141541Srgrimes# 3. All advertising materials mentioning features or use of this software 151541Srgrimes# must display the following acknowledgement: 161541Srgrimes# This product includes software developed by the University of 171541Srgrimes# California, Berkeley and its contributors. 181541Srgrimes# 4. Neither the name of the University nor the names of its contributors 191541Srgrimes# may be used to endorse or promote products derived from this software 201541Srgrimes# without specific prior written permission. 211541Srgrimes# 221541Srgrimes# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 231541Srgrimes# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 241541Srgrimes# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 251541Srgrimes# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 261541Srgrimes# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 271541Srgrimes# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 281541Srgrimes# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 291541Srgrimes# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 301541Srgrimes# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 311541Srgrimes# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 321541Srgrimes# SUCH DAMAGE. 331541Srgrimes# 341541Srgrimes# @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93 351541Srgrimes# 361541Srgrimes 371541Srgrimes# Script to produce VFS front-end sugar. 381541Srgrimes# 391541Srgrimes# usage: vnode_if.sh srcfile 401541Srgrimes# (where srcfile is currently /sys/kern/vnode_if.src) 411541Srgrimes# 421541Srgrimes# These awk scripts are not particularly well written, specifically they 431541Srgrimes# don't use arrays well and figure out the same information repeatedly. 441541Srgrimes# Please rewrite them if you actually understand how to use awk. Note, 451541Srgrimes# they use nawk extensions and gawk's toupper. 461541Srgrimes 471541Srgrimesif [ $# -ne 1 ] ; then 481541Srgrimes echo 'usage: vnode_if.sh srcfile' 491541Srgrimes exit 1 501541Srgrimesfi 511541Srgrimes 521541Srgrimes# Name of the source file. 531541SrgrimesSRC=$1 541541Srgrimes 551541Srgrimes# Names of the created files. 561541SrgrimesCFILE=vnode_if.c 571541SrgrimesHEADER=vnode_if.h 581541Srgrimes 591541Srgrimes# Awk program (must support nawk extensions and gawk's "toupper") 601541Srgrimes# Use "awk" at Berkeley, "gawk" elsewhere. 611541SrgrimesAWK=awk 621541Srgrimes 631541Srgrimes# Print out header information for vnode_if.h. 641541Srgrimescat << END_OF_LEADING_COMMENT > $HEADER 651541Srgrimes/* 661541Srgrimes * This file is produced automatically. 671541Srgrimes * Do not modify anything in here by hand. 681541Srgrimes * 691541Srgrimes * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93 701541Srgrimes */ 711541Srgrimes 721541Srgrimesextern struct vnodeop_desc vop_default_desc; 731541SrgrimesEND_OF_LEADING_COMMENT 741541Srgrimes 751541Srgrimes# Awk script to take vnode_if.src and turn it into vnode_if.h. 761541Srgrimes$AWK ' 771541Srgrimes NF == 0 || $0 ~ "^#" { 781541Srgrimes next; 791541Srgrimes } 801541Srgrimes { 811541Srgrimes # Get the function name. 821541Srgrimes name = $1; 831541Srgrimes uname = toupper(name); 841541Srgrimes 851541Srgrimes # Get the function arguments. 861541Srgrimes for (c1 = 0;; ++c1) { 871541Srgrimes if (getline <= 0) 881541Srgrimes exit 891541Srgrimes if ($0 ~ "^};") 901541Srgrimes break; 911541Srgrimes a[c1] = $0; 921541Srgrimes } 931541Srgrimes 941541Srgrimes # Print out the vop_F_args structure. 951541Srgrimes printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n", 961541Srgrimes name); 971541Srgrimes for (c2 = 0; c2 < c1; ++c2) { 981541Srgrimes c3 = split(a[c2], t); 991541Srgrimes printf("\t"); 1001541Srgrimes if (t[2] ~ "WILLRELE") 1011541Srgrimes c4 = 3; 1021541Srgrimes else 1031541Srgrimes c4 = 2; 1041541Srgrimes for (; c4 < c3; ++c4) 1051541Srgrimes printf("%s ", t[c4]); 1061541Srgrimes beg = match(t[c3], "[^*]"); 1071541Srgrimes printf("%sa_%s\n", 1081541Srgrimes substr(t[c4], 0, beg - 1), substr(t[c4], beg)); 1091541Srgrimes } 1101541Srgrimes printf("};\n"); 1111541Srgrimes 1121541Srgrimes # Print out extern declaration. 1131541Srgrimes printf("extern struct vnodeop_desc %s_desc;\n", name); 1141541Srgrimes 1151541Srgrimes # Print out inline struct. 1161541Srgrimes printf("static inline int %s(", uname); 1171541Srgrimes sep = ", "; 1181541Srgrimes for (c2 = 0; c2 < c1; ++c2) { 1191541Srgrimes if (c2 == c1 - 1) 1201541Srgrimes sep = ")\n"; 1211541Srgrimes c3 = split(a[c2], t); 1221541Srgrimes beg = match(t[c3], "[^*]"); 1231541Srgrimes end = match(t[c3], ";"); 1241541Srgrimes printf("%s%s", substr(t[c3], beg, end - beg), sep); 1251541Srgrimes } 1261541Srgrimes for (c2 = 0; c2 < c1; ++c2) { 1271541Srgrimes c3 = split(a[c2], t); 1281541Srgrimes printf("\t"); 1291541Srgrimes if (t[2] ~ "WILLRELE") 1301541Srgrimes c4 = 3; 1311541Srgrimes else 1321541Srgrimes c4 = 2; 1331541Srgrimes for (; c4 < c3; ++c4) 1341541Srgrimes printf("%s ", t[c4]); 1351541Srgrimes beg = match(t[c3], "[^*]"); 1361541Srgrimes printf("%s%s\n", 1371541Srgrimes substr(t[c4], 0, beg - 1), substr(t[c4], beg)); 1381541Srgrimes } 1391541Srgrimes printf("{\n\tstruct %s_args a;\n\n", name); 1401541Srgrimes printf("\ta.a_desc = VDESC(%s);\n", name); 1411541Srgrimes for (c2 = 0; c2 < c1; ++c2) { 1421541Srgrimes c3 = split(a[c2], t); 1431541Srgrimes printf("\t"); 1441541Srgrimes beg = match(t[c3], "[^*]"); 1451541Srgrimes end = match(t[c3], ";"); 1461541Srgrimes printf("a.a_%s = %s\n", 1471541Srgrimes substr(t[c3], beg, end - beg), substr(t[c3], beg)); 1481541Srgrimes } 1491541Srgrimes c1 = split(a[0], t); 1501541Srgrimes beg = match(t[c1], "[^*]"); 1511541Srgrimes end = match(t[c1], ";"); 1521541Srgrimes printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n", 1531541Srgrimes substr(t[c1], beg, end - beg), name); 1541541Srgrimes }' < $SRC >> $HEADER 1551541Srgrimes 1561541Srgrimes# Print out header information for vnode_if.c. 1571541Srgrimescat << END_OF_LEADING_COMMENT > $CFILE 1581541Srgrimes/* 1591541Srgrimes * This file is produced automatically. 1601541Srgrimes * Do not modify anything in here by hand. 1611541Srgrimes * 1621541Srgrimes * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93 1631541Srgrimes */ 1641541Srgrimes 1651541Srgrimes#include <sys/param.h> 1661541Srgrimes#include <sys/mount.h> 1671541Srgrimes#include <sys/vnode.h> 1681541Srgrimes 1691541Srgrimesstruct vnodeop_desc vop_default_desc = { 1701541Srgrimes 0, 1711541Srgrimes "default", 1721541Srgrimes 0, 1731541Srgrimes NULL, 1741541Srgrimes VDESC_NO_OFFSET, 1751541Srgrimes VDESC_NO_OFFSET, 1761541Srgrimes VDESC_NO_OFFSET, 1771541Srgrimes VDESC_NO_OFFSET, 1781541Srgrimes NULL, 1791541Srgrimes}; 1801541Srgrimes 1811541SrgrimesEND_OF_LEADING_COMMENT 1821541Srgrimes 1831541Srgrimes# Awk script to take vnode_if.src and turn it into vnode_if.c. 1841541Srgrimes$AWK 'function kill_surrounding_ws (s) { 1851541Srgrimes sub (/^[ \t]*/, "", s); 1861541Srgrimes sub (/[ \t]*$/, "", s); 1871541Srgrimes return s; 1881541Srgrimes } 1891541Srgrimes 1901541Srgrimes function read_args() { 1911541Srgrimes numargs = 0; 1921541Srgrimes while (getline ln) { 1931541Srgrimes if (ln ~ /}/) { 1941541Srgrimes break; 1951541Srgrimes }; 1961541Srgrimes 1971541Srgrimes # Delete comments, if any. 1981541Srgrimes gsub (/\/\*.*\*\//, "", ln); 1991541Srgrimes 2001541Srgrimes # Delete leading/trailing space. 2011541Srgrimes ln = kill_surrounding_ws(ln); 2021541Srgrimes 2031541Srgrimes # Pick off direction. 2041541Srgrimes if (1 == sub(/^INOUT[ \t]+/, "", ln)) 2051541Srgrimes dir = "INOUT"; 2061541Srgrimes else if (1 == sub(/^IN[ \t]+/, "", ln)) 2071541Srgrimes dir = "IN"; 2081541Srgrimes else if (1 == sub(/^OUT[ \t]+/, "", ln)) 2091541Srgrimes dir = "OUT"; 2101541Srgrimes else 2111541Srgrimes bail("No IN/OUT direction for \"" ln "\"."); 2121541Srgrimes 2131541Srgrimes # check for "WILLRELE" 2141541Srgrimes if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) { 2151541Srgrimes rele = "WILLRELE"; 2161541Srgrimes } else { 2171541Srgrimes rele = "WONTRELE"; 2181541Srgrimes }; 2191541Srgrimes 2201541Srgrimes # kill trailing ; 2211541Srgrimes if (1 != sub (/;$/, "", ln)) { 2221541Srgrimes bail("Missing end-of-line ; in \"" ln "\"."); 2231541Srgrimes }; 2241541Srgrimes 2251541Srgrimes # pick off variable name 2261541Srgrimes if (!(i = match(ln, /[A-Za-z0-9_]+$/))) { 2271541Srgrimes bail("Missing var name \"a_foo\" in \"" ln "\"."); 2281541Srgrimes }; 2291541Srgrimes arg = substr (ln, i); 2301541Srgrimes # Want to <<substr(ln, i) = "";>>, but nawk cannot. 2311541Srgrimes # Hack around this. 2321541Srgrimes ln = substr(ln, 1, i-1); 2331541Srgrimes 2341541Srgrimes # what is left must be type 2351541Srgrimes # (put clean it up some) 2361541Srgrimes type = ln; 2371541Srgrimes gsub (/[ \t]+/, " ", type); # condense whitespace 2381541Srgrimes type = kill_surrounding_ws(type); 2391541Srgrimes 2401541Srgrimes # (boy this was easier in Perl) 2411541Srgrimes 2421541Srgrimes numargs++; 2431541Srgrimes dirs[numargs] = dir; 2441541Srgrimes reles[numargs] = rele; 2451541Srgrimes types[numargs] = type; 2461541Srgrimes args[numargs] = arg; 2471541Srgrimes }; 2481541Srgrimes } 2491541Srgrimes 2501541Srgrimes function generate_operation_vp_offsets() { 2511541Srgrimes printf ("int %s_vp_offsets[] = {\n", name); 2521541Srgrimes # as a side effect, figure out the releflags 2531541Srgrimes releflags = ""; 2541541Srgrimes vpnum = 0; 2551541Srgrimes for (i=1; i<=numargs; i++) { 2561541Srgrimes if (types[i] == "struct vnode *") { 2571541Srgrimes printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n", 2581541Srgrimes name, args[i]); 2591541Srgrimes if (reles[i] == "WILLRELE") { 2601541Srgrimes releflags = releflags "|VDESC_VP" vpnum "_WILLRELE"; 2611541Srgrimes }; 2621541Srgrimes vpnum++; 2631541Srgrimes }; 2641541Srgrimes }; 2651541Srgrimes sub (/^\|/, "", releflags); 2661541Srgrimes print "\tVDESC_NO_OFFSET"; 2671541Srgrimes print "};"; 2681541Srgrimes } 2691541Srgrimes 2701541Srgrimes function find_arg_with_type (type) { 2711541Srgrimes for (i=1; i<=numargs; i++) { 2721541Srgrimes if (types[i] == type) { 2731541Srgrimes return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")"; 2741541Srgrimes }; 2751541Srgrimes }; 2761541Srgrimes return "VDESC_NO_OFFSET"; 2771541Srgrimes } 2781541Srgrimes 2791541Srgrimes function generate_operation_desc() { 2801541Srgrimes printf ("struct vnodeop_desc %s_desc = {\n", name); 2811541Srgrimes # offset 2821541Srgrimes printf ("\t0,\n"); 2831541Srgrimes # printable name 2841541Srgrimes printf ("\t\"%s\",\n", name); 2851541Srgrimes # flags 2861541Srgrimes vppwillrele = ""; 2871541Srgrimes for (i=1; i<=numargs; i++) { 2881541Srgrimes if (types[i] == "struct vnode **" && 2891541Srgrimes (reles[i] == "WILLRELE")) { 2901541Srgrimes vppwillrele = "|VDESC_VPP_WILLRELE"; 2911541Srgrimes }; 2921541Srgrimes }; 2931541Srgrimes if (releflags == "") { 2941541Srgrimes printf ("\t0%s,\n", vppwillrele); 2951541Srgrimes } else { 2961541Srgrimes printf ("\t%s%s,\n", releflags, vppwillrele); 2971541Srgrimes }; 2981541Srgrimes # vp offsets 2991541Srgrimes printf ("\t%s_vp_offsets,\n", name); 3001541Srgrimes # vpp (if any) 3011541Srgrimes printf ("\t%s,\n", find_arg_with_type("struct vnode **")); 3021541Srgrimes # cred (if any) 3031541Srgrimes printf ("\t%s,\n", find_arg_with_type("struct ucred *")); 3041541Srgrimes # proc (if any) 3051541Srgrimes printf ("\t%s,\n", find_arg_with_type("struct proc *")); 3061541Srgrimes # componentname 3071541Srgrimes printf ("\t%s,\n", find_arg_with_type("struct componentname *")); 3081541Srgrimes # transport layer information 3091541Srgrimes printf ("\tNULL,\n};\n"); 3101541Srgrimes } 3111541Srgrimes 3121541Srgrimes NF == 0 || $0 ~ "^#" { 3131541Srgrimes next; 3141541Srgrimes } 3151541Srgrimes { 3161541Srgrimes # get the function name 3171541Srgrimes name = $1; 3181541Srgrimes 3191541Srgrimes # get the function arguments 3201541Srgrimes read_args(); 3211541Srgrimes 3221541Srgrimes # Print out the vop_F_vp_offsets structure. This all depends 3231541Srgrimes # on naming conventions and nothing else. 3241541Srgrimes generate_operation_vp_offsets(); 3251541Srgrimes 3261541Srgrimes # Print out the vnodeop_desc structure. 3271541Srgrimes generate_operation_desc(); 3281541Srgrimes 3291541Srgrimes printf "\n"; 3301541Srgrimes 3311541Srgrimes }' < $SRC >> $CFILE 3321541Srgrimes# THINGS THAT DON'T WORK RIGHT YET. 3331541Srgrimes# 3341541Srgrimes# Two existing BSD vnodeops (bwrite and strategy) don't take any vnodes as 3351541Srgrimes# arguments. This means that these operations can't function successfully 3361541Srgrimes# through a bypass routine. 3371541Srgrimes# 3381541Srgrimes# Bwrite and strategy will be replaced when the VM page/buffer cache 3391541Srgrimes# integration happens. 3401541Srgrimes# 3411541Srgrimes# To get around this problem for now we handle these ops as special cases. 3421541Srgrimes 3431541Srgrimescat << END_OF_SPECIAL_CASES >> $HEADER 3441541Srgrimes#include <sys/buf.h> 3451541Srgrimesstruct vop_strategy_args { 3461541Srgrimes struct vnodeop_desc *a_desc; 3471541Srgrimes struct buf *a_bp; 3481541Srgrimes}; 3491541Srgrimesextern struct vnodeop_desc vop_strategy_desc; 3501541Srgrimesstatic inline int VOP_STRATEGY(bp) 3511541Srgrimes struct buf *bp; 3521541Srgrimes{ 3531541Srgrimes struct vop_strategy_args a; 3541541Srgrimes 3551541Srgrimes a.a_desc = VDESC(vop_strategy); 3561541Srgrimes a.a_bp = bp; 3571541Srgrimes return (VCALL((bp)->b_vp, VOFFSET(vop_strategy), &a)); 3581541Srgrimes} 3591541Srgrimes 3601541Srgrimesstruct vop_bwrite_args { 3611541Srgrimes struct vnodeop_desc *a_desc; 3621541Srgrimes struct buf *a_bp; 3631541Srgrimes}; 3641541Srgrimesextern struct vnodeop_desc vop_bwrite_desc; 3651541Srgrimesstatic inline int VOP_BWRITE(bp) 3661541Srgrimes struct buf *bp; 3671541Srgrimes{ 3681541Srgrimes struct vop_bwrite_args a; 3691541Srgrimes 3701541Srgrimes a.a_desc = VDESC(vop_bwrite); 3711541Srgrimes a.a_bp = bp; 3721541Srgrimes return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a)); 3731541Srgrimes} 3741541SrgrimesEND_OF_SPECIAL_CASES 3751541Srgrimes 3761541Srgrimescat << END_OF_SPECIAL_CASES >> $CFILE 3771541Srgrimesint vop_strategy_vp_offsets[] = { 3781541Srgrimes VDESC_NO_OFFSET 3791541Srgrimes}; 3801541Srgrimesstruct vnodeop_desc vop_strategy_desc = { 3811541Srgrimes 0, 3821541Srgrimes "vop_strategy", 3831541Srgrimes 0, 3841541Srgrimes vop_strategy_vp_offsets, 3851541Srgrimes VDESC_NO_OFFSET, 3861541Srgrimes VDESC_NO_OFFSET, 3871541Srgrimes VDESC_NO_OFFSET, 3881541Srgrimes VDESC_NO_OFFSET, 3891541Srgrimes NULL, 3901541Srgrimes}; 3911541Srgrimesint vop_bwrite_vp_offsets[] = { 3921541Srgrimes VDESC_NO_OFFSET 3931541Srgrimes}; 3941541Srgrimesstruct vnodeop_desc vop_bwrite_desc = { 3951541Srgrimes 0, 3961541Srgrimes "vop_bwrite", 3971541Srgrimes 0, 3981541Srgrimes vop_bwrite_vp_offsets, 3991541Srgrimes VDESC_NO_OFFSET, 4001541Srgrimes VDESC_NO_OFFSET, 4011541Srgrimes VDESC_NO_OFFSET, 4021541Srgrimes VDESC_NO_OFFSET, 4031541Srgrimes NULL, 4041541Srgrimes}; 4051541SrgrimesEND_OF_SPECIAL_CASES 4061541Srgrimes 4071541Srgrimes# Add the vfs_op_descs array to the C file. 4081541Srgrimes$AWK ' 4091541Srgrimes BEGIN { 4101541Srgrimes printf("\nstruct vnodeop_desc *vfs_op_descs[] = {\n"); 4111541Srgrimes printf("\t&vop_default_desc, /* MUST BE FIRST */\n"); 4121541Srgrimes printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n"); 4131541Srgrimes printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n"); 4141541Srgrimes } 4151541Srgrimes END { 4161541Srgrimes printf("\tNULL\n};\n"); 4171541Srgrimes } 4181541Srgrimes NF == 0 || $0 ~ "^#" { 4191541Srgrimes next; 4201541Srgrimes } 4211541Srgrimes { 4221541Srgrimes # Get the function name. 4231541Srgrimes printf("\t&%s_desc,\n", $1); 4241541Srgrimes 4251541Srgrimes # Skip the function arguments. 4261541Srgrimes for (;;) { 4271541Srgrimes if (getline <= 0) 4281541Srgrimes exit 4291541Srgrimes if ($0 ~ "^};") 4301541Srgrimes break; 4311541Srgrimes } 4321541Srgrimes }' < $SRC >> $CFILE 4331541Srgrimes 434