vnode_if.awk revision 11921
117680Spst#!/bin/sh - 217680Spst# 317680Spst# Copyright (c) 1992, 1993 417680Spst# The Regents of the University of California. All rights reserved. 517680Spst# 617680Spst# Redistribution and use in source and binary forms, with or without 717680Spst# modification, are permitted provided that the following conditions 817680Spst# are met: 917680Spst# 1. Redistributions of source code must retain the above copyright 1017680Spst# notice, this list of conditions and the following disclaimer. 1117680Spst# 2. Redistributions in binary form must reproduce the above copyright 1217680Spst# notice, this list of conditions and the following disclaimer in the 1317680Spst# documentation and/or other materials provided with the distribution. 1417680Spst# 3. All advertising materials mentioning features or use of this software 1517680Spst# must display the following acknowledgement: 1617680Spst# This product includes software developed by the University of 1717680Spst# California, Berkeley and its contributors. 1817680Spst# 4. Neither the name of the University nor the names of its contributors 1917680Spst# may be used to endorse or promote products derived from this software 2057278Sfenner# without specific prior written permission. 2157278Sfenner# 2217680Spst# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2317680Spst# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2417680Spst# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25127675Sbms# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26127675Sbms# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2717680Spst# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2817680Spst# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2956893Sfenner# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3056893Sfenner# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3156893Sfenner# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3256893Sfenner# SUCH DAMAGE. 33127675Sbms# 3417680Spst# @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93 3556893Sfenner# $Id: vnode_if.sh,v 1.6 1995/09/11 16:05:16 bde Exp $ 3656893Sfenner# 3756893Sfenner 3856893Sfenner# Script to produce VFS front-end sugar. 3956893Sfenner# 4056893Sfenner# usage: vnode_if.sh srcfile 4156893Sfenner# (where srcfile is currently /sys/kern/vnode_if.src) 4257278Sfenner# 4357278Sfenner# These awk scripts are not particularly well written, specifically they 4456893Sfenner# don't use arrays well and figure out the same information repeatedly. 4556893Sfenner# Please rewrite them if you actually understand how to use awk. Note, 4656893Sfenner# they use nawk extensions and gawk's toupper. 4756893Sfenner 4857278Sfennerif [ $# -ne 1 ] ; then 4957278Sfenner echo 'usage: vnode_if.sh srcfile' 5056893Sfenner exit 1 5156893Sfennerfi 5256893Sfenner 5356893Sfenner# Name of the source file. 5456893SfennerSRC=$1 5517680Spst 5617680Spst# Names of the created files. 5717680SpstCFILE=vnode_if.c 5817680SpstHEADER=vnode_if.h 5917680Spst 6056893Sfenner# Awk program (must support nawk extensions and gawk's "toupper") 6117680Spst# Use "awk" at Berkeley, "gawk" elsewhere. 6275118SfennerAWK=awk 6375118Sfenner 6456893Sfenner# Print out header information for vnode_if.h. 6556893Sfennercat << END_OF_LEADING_COMMENT > $HEADER 6656893Sfenner/* 6756893Sfenner * This file is produced automatically. 6856893Sfenner * Do not modify anything in here by hand. 6998527Sfenner * 7098527Sfenner * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93 7156893Sfenner */ 7298527Sfenner 7398527Sfennerextern struct vnodeop_desc vop_default_desc; 7498527Sfenner 7598527Sfenner#include <vm/vm.h> 7656893Sfenner#include <vm/vm_page.h> 7798527SfennerEND_OF_LEADING_COMMENT 7898527Sfenner 7998527Sfenner# Awk script to take vnode_if.src and turn it into vnode_if.h. 8098527Sfenner$AWK ' 8198527Sfenner NF == 0 || $0 ~ "^#" { 8298527Sfenner next; 8398527Sfenner } 8498527Sfenner { 8598527Sfenner # Get the function name. 8698527Sfenner name = $1; 8798527Sfenner uname = toupper(name); 8898527Sfenner 8956893Sfenner # Get the function arguments. 9056893Sfenner for (c1 = 0;; ++c1) { 9156893Sfenner if (getline <= 0) 9298527Sfenner exit 9398527Sfenner if ($0 ~ "^};") 9456893Sfenner break; 9556893Sfenner a[c1] = $0; 9698527Sfenner } 9798527Sfenner 9898527Sfenner # Print out the vop_F_args structure. 9998527Sfenner printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n", 10098527Sfenner name); 10198527Sfenner for (c2 = 0; c2 < c1; ++c2) { 10298527Sfenner c3 = split(a[c2], t); 10398527Sfenner printf("\t"); 10498527Sfenner if (t[2] ~ "WILLRELE") 10598527Sfenner c4 = 3; 10698527Sfenner else 10798527Sfenner c4 = 2; 10856893Sfenner for (; c4 < c3; ++c4) 10998527Sfenner printf("%s ", t[c4]); 11098527Sfenner beg = match(t[c3], "[^*]"); 11198527Sfenner printf("%sa_%s\n", 11298527Sfenner substr(t[c4], 0, beg - 1), substr(t[c4], beg)); 11398527Sfenner } 11498527Sfenner printf("};\n"); 11598527Sfenner 11698527Sfenner # Print out extern declaration. 11798527Sfenner printf("extern struct vnodeop_desc %s_desc;\n", name); 118127675Sbms 11998527Sfenner # Print out prototype. 12098527Sfenner printf("static int %s __P((\n", uname); 12198527Sfenner sep = ",\n"; 12298527Sfenner for (c2 = 0; c2 < c1; ++c2) { 12398527Sfenner if (c2 == c1 - 1) 12498527Sfenner sep = "));\n"; 12598527Sfenner c3 = split(a[c2], t); 12698527Sfenner printf("\t"); 12798527Sfenner if (t[2] ~ "WILLRELE") 128127675Sbms c4 = 3; 12998527Sfenner else 13098527Sfenner c4 = 2; 13198527Sfenner for (; c4 < c3; ++c4) 13298527Sfenner printf("%s ", t[c4]); 13398527Sfenner beg = match(t[c3], "[^*]"); 13498527Sfenner end = match(t[c3], ";"); 13598527Sfenner printf("%s%s%s", 13656893Sfenner substr(t[c4], 0, beg - 1), 13756893Sfenner substr(t[c4], beg, end - beg), sep); 13856893Sfenner } 13998527Sfenner 14098527Sfenner # Print out inline struct. 14198527Sfenner printf("static inline int %s(", uname); 14298527Sfenner sep = ", "; 14356893Sfenner for (c2 = 0; c2 < c1; ++c2) { 14498527Sfenner if (c2 == c1 - 1) 14556893Sfenner sep = ")\n"; 14698527Sfenner c3 = split(a[c2], t); 14798527Sfenner beg = match(t[c3], "[^*]"); 14856893Sfenner end = match(t[c3], ";"); 14956893Sfenner printf("%s%s", substr(t[c3], beg, end - beg), sep); 15017680Spst } 15156893Sfenner for (c2 = 0; c2 < c1; ++c2) { 15217680Spst c3 = split(a[c2], t); 15398527Sfenner printf("\t"); 15498527Sfenner if (t[2] ~ "WILLRELE") 15517680Spst c4 = 3; 15698527Sfenner else 15798527Sfenner c4 = 2; 15898527Sfenner for (; c4 < c3; ++c4) 15917680Spst printf("%s ", t[c4]); 160127675Sbms beg = match(t[c3], "[^*]"); 16198527Sfenner printf("%s%s\n", 16217680Spst substr(t[c4], 0, beg - 1), substr(t[c4], beg)); 16398527Sfenner } 16498527Sfenner printf("{\n\tstruct %s_args a;\n\n", name); 16598527Sfenner printf("\ta.a_desc = VDESC(%s);\n", name); 16698527Sfenner for (c2 = 0; c2 < c1; ++c2) { 16798527Sfenner c3 = split(a[c2], t); 16898527Sfenner printf("\t"); 16998527Sfenner beg = match(t[c3], "[^*]"); 17056893Sfenner end = match(t[c3], ";"); 17198527Sfenner printf("a.a_%s = %s\n", 17298527Sfenner substr(t[c3], beg, end - beg), substr(t[c3], beg)); 17356893Sfenner } 17498527Sfenner c1 = split(a[0], t); 17598527Sfenner beg = match(t[c1], "[^*]"); 17656893Sfenner end = match(t[c1], ";"); 17798527Sfenner printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n", 17898527Sfenner substr(t[c1], beg, end - beg), name); 17956893Sfenner }' < $SRC >> $HEADER 18098527Sfenner 18156893Sfenner# Print out header information for vnode_if.c. 18298527Sfennercat << END_OF_LEADING_COMMENT > $CFILE 18398527Sfenner/* 18498527Sfenner * This file is produced automatically. 18598527Sfenner * Do not modify anything in here by hand. 18698527Sfenner * 18798527Sfenner * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93 18898527Sfenner */ 18917680Spst 19098527Sfenner#include <sys/param.h> 19198527Sfenner#include <sys/mount.h> 19298527Sfenner#include <sys/vnode.h> 19398527Sfenner#include <vm/vm.h> 19498527Sfenner#include <vm/vm_page.h> 19598527Sfenner 19698527Sfennerstruct vnodeop_desc vop_default_desc = { 19798527Sfenner 0, 19898527Sfenner "default", 19998527Sfenner 0, 20098527Sfenner NULL, 20198527Sfenner VDESC_NO_OFFSET, 20298527Sfenner VDESC_NO_OFFSET, 20398527Sfenner VDESC_NO_OFFSET, 20498527Sfenner VDESC_NO_OFFSET, 20598527Sfenner NULL, 20698527Sfenner}; 20798527Sfenner 20898527SfennerEND_OF_LEADING_COMMENT 20998527Sfenner 21098527Sfenner# Awk script to take vnode_if.src and turn it into vnode_if.c. 21198527Sfenner$AWK 'function kill_surrounding_ws (s) { 21256893Sfenner sub (/^[ \t]*/, "", s); 21398527Sfenner sub (/[ \t]*$/, "", s); 21498527Sfenner return s; 21598527Sfenner } 21698527Sfenner 21798527Sfenner function read_args() { 21898527Sfenner numargs = 0; 21998527Sfenner while (getline ln) { 22098527Sfenner if (ln ~ /}/) { 22198527Sfenner break; 22298527Sfenner }; 22398527Sfenner 22456893Sfenner # Delete comments, if any. 22556893Sfenner gsub (/\/\*.*\*\//, "", ln); 22698527Sfenner 22798527Sfenner # Delete leading/trailing space. 22898527Sfenner ln = kill_surrounding_ws(ln); 22956893Sfenner 23056893Sfenner # Pick off direction. 23198527Sfenner if (1 == sub(/^INOUT[ \t]+/, "", ln)) 23298527Sfenner dir = "INOUT"; 23398527Sfenner else if (1 == sub(/^IN[ \t]+/, "", ln)) 23498527Sfenner dir = "IN"; 23598527Sfenner else if (1 == sub(/^OUT[ \t]+/, "", ln)) 23698527Sfenner dir = "OUT"; 23798527Sfenner else 23898527Sfenner bail("No IN/OUT direction for \"" ln "\"."); 23998527Sfenner 24098527Sfenner # check for "WILLRELE" 24198527Sfenner if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) { 24298527Sfenner rele = "WILLRELE"; 24398527Sfenner } else { 24498527Sfenner rele = "WONTRELE"; 24598527Sfenner }; 24698527Sfenner 24798527Sfenner # kill trailing ; 24856893Sfenner if (1 != sub (/;$/, "", ln)) { 24998527Sfenner bail("Missing end-of-line ; in \"" ln "\"."); 25098527Sfenner }; 25198527Sfenner 25217680Spst # pick off variable name 25356893Sfenner if (!(i = match(ln, /[A-Za-z0-9_]+$/))) { 25498527Sfenner bail("Missing var name \"a_foo\" in \"" ln "\"."); 25598527Sfenner }; 25617680Spst arg = substr (ln, i); 25756893Sfenner # Want to <<substr(ln, i) = "";>>, but nawk cannot. 25856893Sfenner # Hack around this. 25956893Sfenner ln = substr(ln, 1, i-1); 26098527Sfenner 26198527Sfenner # what is left must be type 26298527Sfenner # (put clean it up some) 26356893Sfenner type = ln; 26456893Sfenner gsub (/[ \t]+/, " ", type); # condense whitespace 26556893Sfenner type = kill_surrounding_ws(type); 26656893Sfenner 26798527Sfenner # (boy this was easier in Perl) 26898527Sfenner 26998527Sfenner numargs++; 27056893Sfenner dirs[numargs] = dir; 27198527Sfenner reles[numargs] = rele; 27298527Sfenner types[numargs] = type; 27398527Sfenner args[numargs] = arg; 27498527Sfenner }; 27598527Sfenner } 27698527Sfenner 27798527Sfenner function generate_operation_vp_offsets() { 27898527Sfenner printf ("static int %s_vp_offsets[] = {\n", name); 27998527Sfenner # as a side effect, figure out the releflags 28098527Sfenner releflags = ""; 28198527Sfenner vpnum = 0; 28298527Sfenner for (i=1; i<=numargs; i++) { 28398527Sfenner if (types[i] == "struct vnode *") { 28498527Sfenner printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n", 28556893Sfenner name, args[i]); 28698527Sfenner if (reles[i] == "WILLRELE") { 28798527Sfenner releflags = releflags "|VDESC_VP" vpnum "_WILLRELE"; 28856893Sfenner }; 28998527Sfenner vpnum++; 29098527Sfenner }; 29198527Sfenner }; 29298527Sfenner sub (/^\|/, "", releflags); 29398527Sfenner print "\tVDESC_NO_OFFSET"; 29498527Sfenner print "};"; 29598527Sfenner } 29656893Sfenner 29798527Sfenner function find_arg_with_type (type) { 29856893Sfenner for (i=1; i<=numargs; i++) { 29998527Sfenner if (types[i] == type) { 30056893Sfenner return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")"; 30198527Sfenner }; 30256893Sfenner }; 30398527Sfenner return "VDESC_NO_OFFSET"; 30498527Sfenner } 30598527Sfenner 30698527Sfenner function generate_operation_desc() { 30798527Sfenner printf ("struct vnodeop_desc %s_desc = {\n", name); 30898527Sfenner # offset 30998527Sfenner printf ("\t0,\n"); 31098527Sfenner # printable name 31198527Sfenner printf ("\t\"%s\",\n", name); 31298527Sfenner # flags 31398527Sfenner vppwillrele = ""; 31498527Sfenner for (i=1; i<=numargs; i++) { 31598527Sfenner if (types[i] == "struct vnode **" && 31698527Sfenner (reles[i] == "WILLRELE")) { 31756893Sfenner vppwillrele = "|VDESC_VPP_WILLRELE"; 31898527Sfenner }; 31998527Sfenner }; 32098527Sfenner if (releflags == "") { 32198527Sfenner printf ("\t0%s,\n", vppwillrele); 32298527Sfenner } else { 32398527Sfenner printf ("\t%s%s,\n", releflags, vppwillrele); 32498527Sfenner }; 32598527Sfenner # vp offsets 32698527Sfenner printf ("\t%s_vp_offsets,\n", name); 32798527Sfenner # vpp (if any) 32898527Sfenner printf ("\t%s,\n", find_arg_with_type("struct vnode **")); 32998527Sfenner # cred (if any) 33098527Sfenner printf ("\t%s,\n", find_arg_with_type("struct ucred *")); 33198527Sfenner # proc (if any) 33298527Sfenner printf ("\t%s,\n", find_arg_with_type("struct proc *")); 33398527Sfenner # componentname 33498527Sfenner printf ("\t%s,\n", find_arg_with_type("struct componentname *")); 33598527Sfenner # transport layer information 33698527Sfenner printf ("\tNULL,\n};\n"); 33798527Sfenner } 33898527Sfenner 33998527Sfenner NF == 0 || $0 ~ "^#" { 34098527Sfenner next; 34198527Sfenner } 34298527Sfenner { 34398527Sfenner # get the function name 34498527Sfenner name = $1; 34598527Sfenner 34656893Sfenner # get the function arguments 34798527Sfenner read_args(); 34856893Sfenner 34956893Sfenner # Print out the vop_F_vp_offsets structure. This all depends 35098527Sfenner # on naming conventions and nothing else. 35198527Sfenner generate_operation_vp_offsets(); 35256893Sfenner 35356893Sfenner # Print out the vnodeop_desc structure. 35456893Sfenner generate_operation_desc(); 35556893Sfenner 35656893Sfenner printf "\n"; 35756893Sfenner 35856893Sfenner }' < $SRC >> $CFILE 35956893Sfenner# THINGS THAT DON'T WORK RIGHT YET. 36056893Sfenner# 36156893Sfenner# Two existing BSD vnodeops (bwrite and strategy) don't take any vnodes as 36256893Sfenner# arguments. This means that these operations can't function successfully 36356893Sfenner# through a bypass routine. 36456893Sfenner# 36556893Sfenner# Bwrite and strategy will be replaced when the VM page/buffer cache 36656893Sfenner# integration happens. 36775118Sfenner# 36898527Sfenner# To get around this problem for now we handle these ops as special cases. 36957278Sfenner 37056893Sfennercat << END_OF_SPECIAL_CASES >> $HEADER 37156893Sfenner#include <sys/buf.h> 37298527Sfennerstruct vop_strategy_args { 37357278Sfenner struct vnodeop_desc *a_desc; 37456893Sfenner struct buf *a_bp; 37556893Sfenner}; 37656893Sfennerextern struct vnodeop_desc vop_strategy_desc; 37756893Sfennerstatic int VOP_STRATEGY __P(( 37856893Sfenner struct buf *bp)); 37956893Sfennerstatic inline int VOP_STRATEGY(bp) 38056893Sfenner struct buf *bp; 38156893Sfenner{ 38256893Sfenner struct vop_strategy_args a; 38356893Sfenner 38456893Sfenner a.a_desc = VDESC(vop_strategy); 38556893Sfenner a.a_bp = bp; 38656893Sfenner return (VCALL((bp)->b_vp, VOFFSET(vop_strategy), &a)); 38756893Sfenner} 38856893Sfenner 38956893Sfennerstruct vop_bwrite_args { 39056893Sfenner struct vnodeop_desc *a_desc; 39156893Sfenner struct buf *a_bp; 39256893Sfenner}; 39356893Sfennerextern struct vnodeop_desc vop_bwrite_desc; 39456893Sfennerstatic int VOP_BWRITE __P(( 39556893Sfenner struct buf *bp)); 39656893Sfennerstatic inline int VOP_BWRITE(bp) 39756893Sfenner struct buf *bp; 39856893Sfenner{ 39956893Sfenner struct vop_bwrite_args a; 40056893Sfenner 40156893Sfenner a.a_desc = VDESC(vop_bwrite); 40256893Sfenner a.a_bp = bp; 40356893Sfenner return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a)); 40456893Sfenner} 40556893SfennerEND_OF_SPECIAL_CASES 40656893Sfenner 40756893Sfennercat << END_OF_SPECIAL_CASES >> $CFILE 40856893Sfennerint vop_strategy_vp_offsets[] = { 40956893Sfenner VDESC_NO_OFFSET 41056893Sfenner}; 41156893Sfennerstruct vnodeop_desc vop_strategy_desc = { 41256893Sfenner 0, 41356893Sfenner "vop_strategy", 41456893Sfenner 0, 41556893Sfenner vop_strategy_vp_offsets, 41656893Sfenner VDESC_NO_OFFSET, 41756893Sfenner VDESC_NO_OFFSET, 41856893Sfenner VDESC_NO_OFFSET, 41956893Sfenner VDESC_NO_OFFSET, 42056893Sfenner NULL, 42156893Sfenner}; 42256893Sfennerint vop_bwrite_vp_offsets[] = { 42356893Sfenner VDESC_NO_OFFSET 42456893Sfenner}; 42556893Sfennerstruct vnodeop_desc vop_bwrite_desc = { 42656893Sfenner 0, 42756893Sfenner "vop_bwrite", 42856893Sfenner 0, 42956893Sfenner vop_bwrite_vp_offsets, 43056893Sfenner VDESC_NO_OFFSET, 43156893Sfenner VDESC_NO_OFFSET, 43256893Sfenner VDESC_NO_OFFSET, 43356893Sfenner VDESC_NO_OFFSET, 43456893Sfenner NULL, 43556893Sfenner}; 43656893SfennerEND_OF_SPECIAL_CASES 43756893Sfenner 43856893Sfenner# Add the vfs_op_descs array to the C file. 43956893Sfenner$AWK ' 44056893Sfenner BEGIN { 44156893Sfenner printf("\nstruct vnodeop_desc *vfs_op_descs[] = {\n"); 44256893Sfenner printf("\t&vop_default_desc, /* MUST BE FIRST */\n"); 44356893Sfenner printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n"); 44456893Sfenner printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n"); 44556893Sfenner } 44656893Sfenner END { 44756893Sfenner printf("\tNULL\n};\n"); 44856893Sfenner } 449127675Sbms NF == 0 || $0 ~ "^#" { 45056893Sfenner next; 45156893Sfenner } 45256893Sfenner { 45356893Sfenner # Get the function name. 45456893Sfenner printf("\t&%s_desc,\n", $1); 45556893Sfenner 45656893Sfenner # Skip the function arguments. 45798527Sfenner for (;;) { 45856893Sfenner if (getline <= 0) 45956893Sfenner exit 46056893Sfenner if ($0 ~ "^};") 46156893Sfenner break; 46256893Sfenner } 46398527Sfenner }' < $SRC >> $CFILE 46456893Sfenner 46556893Sfenner