154646Smckusick#!/bin/sh - 254646Smckusick# 354646Smckusick# Copyright (c) 1992 The Regents of the University of California. 454646Smckusick# All rights reserved. 554646Smckusick# 654646Smckusick# %sccs.include.redist.sh% 754646Smckusick# 8*55323Sheideman# @(#)vnode_if.sh 7.4 (Berkeley) 07/17/92 954646Smckusick# 1054646Smckusick 1154646Smckusick# Script to produce VFS front-end sugar. 1254725Sbostic# 1354725Sbostic# usage: vnode_if.sh srcfile 1454725Sbostic# (where srcfile is currently /sys/kern/vnode_if.src) 1554725Sbostic# 1654725Sbostic# These awk scripts are not particularly well written, specifically they 1754725Sbostic# don't use arrays well and figure out the same information repeatedly. 1854725Sbostic# Please rewrite them if you actually understand how to use awk. Note, 19*55323Sheideman# they use nawk extensions and gawk's toupper. 2054646Smckusick 2154725Sbosticif [ $# -ne 1 ] ; then 22*55323Sheideman echo 'usage: vnode_if.sh srcfile' 2354725Sbostic exit 1 2454725Sbosticfi 2554725Sbostic 2654725Sbostic# Name of the source file. 2754725SbosticSRC=$1 2854725Sbostic 2954725Sbostic# Names of the created files. 3054725SbosticCFILE=vnode_if.c 3154725SbosticHEADER=vnode_if.h 3254725Sbostic 33*55323Sheideman# Awk program (must support nawk extensions and gawk's "toupper") 34*55323Sheideman# Use "awk" at Berkeley, "gawk" elsewhere. 35*55323SheidemanAWK=awk 36*55323Sheideman 3754725Sbostic# Print out header information for vnode_if.h. 3854725Sbosticcat << END_OF_LEADING_COMMENT > $HEADER 3954646Smckusick/* 4054727Sbostic * This file is produced automatically. 4154646Smckusick * Do not modify anything in here by hand. 4254646Smckusick * 43*55323Sheideman * Created from @(#)vnode_if.sh 7.4 (Berkeley) 07/17/92 4454646Smckusick */ 4554725Sbostic 4654646Smckusickextern struct vnodeop_desc vop_default_desc; 4754646SmckusickEND_OF_LEADING_COMMENT 4854646Smckusick 4954646Smckusick# Awk script to take vnode_if.src and turn it into vnode_if.h. 50*55323Sheideman$AWK ' 5154646Smckusick NF == 0 || $0 ~ "^#" { 5254646Smckusick next; 5354646Smckusick } 5454646Smckusick { 5554725Sbostic # Get the function name. 5654646Smckusick name = $1; 5754646Smckusick uname = toupper(name); 5854646Smckusick 5954725Sbostic # Get the function arguments. 6054646Smckusick for (c1 = 0;; ++c1) { 6154646Smckusick if (getline <= 0) 6254646Smckusick exit 6354646Smckusick if ($0 ~ "^};") 6454646Smckusick break; 6554646Smckusick a[c1] = $0; 6654646Smckusick } 6754646Smckusick 6854725Sbostic # Print out the vop_F_args structure. 6954646Smckusick printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n", 7054646Smckusick name); 7154646Smckusick for (c2 = 0; c2 < c1; ++c2) { 7254646Smckusick c3 = split(a[c2], t); 7354646Smckusick printf("\t"); 74*55323Sheideman if (t[2] ~ "WILLRELE") 75*55323Sheideman c4 = 3; 76*55323Sheideman else 77*55323Sheideman c4 = 2; 78*55323Sheideman for (; c4 < c3; ++c4) 7954646Smckusick printf("%s ", t[c4]); 8054646Smckusick beg = match(t[c3], "[^*]"); 8154646Smckusick printf("%sa_%s\n", 8254646Smckusick substr(t[c4], 0, beg - 1), substr(t[c4], beg)); 8354646Smckusick } 8454646Smckusick printf("};\n"); 8554646Smckusick 8654725Sbostic # Print out extern declaration. 8754646Smckusick printf("extern struct vnodeop_desc %s_desc;\n", name); 8854646Smckusick 8954725Sbostic # Print out inline struct. 9054646Smckusick printf("static inline int %s(", uname); 9154646Smckusick sep = ", "; 9254646Smckusick for (c2 = 0; c2 < c1; ++c2) { 9354646Smckusick if (c2 == c1 - 1) 9454646Smckusick sep = ")\n"; 9554646Smckusick c3 = split(a[c2], t); 9654646Smckusick beg = match(t[c3], "[^*]"); 9754646Smckusick end = match(t[c3], ";"); 9854646Smckusick printf("%s%s", substr(t[c3], beg, end - beg), sep); 9954646Smckusick } 10054646Smckusick for (c2 = 0; c2 < c1; ++c2) { 10154646Smckusick c3 = split(a[c2], t); 10254646Smckusick printf("\t"); 103*55323Sheideman if (t[2] ~ "WILLRELE") 104*55323Sheideman c4 = 3; 105*55323Sheideman else 106*55323Sheideman c4 = 2; 107*55323Sheideman for (; c4 < c3; ++c4) 10854646Smckusick printf("%s ", t[c4]); 10954646Smckusick beg = match(t[c3], "[^*]"); 11054646Smckusick printf("%s%s\n", 11154646Smckusick substr(t[c4], 0, beg - 1), substr(t[c4], beg)); 11254646Smckusick } 11354646Smckusick printf("{\n\tstruct %s_args a;\n\n", name); 11454646Smckusick printf("\ta.a_desc = VDESC(%s);\n", name); 11554646Smckusick for (c2 = 0; c2 < c1; ++c2) { 11654646Smckusick c3 = split(a[c2], t); 11754646Smckusick printf("\t"); 11854646Smckusick beg = match(t[c3], "[^*]"); 11954646Smckusick end = match(t[c3], ";"); 12054646Smckusick printf("a.a_%s = %s\n", 12154646Smckusick substr(t[c3], beg, end - beg), substr(t[c3], beg)); 12254646Smckusick } 12354646Smckusick c1 = split(a[0], t); 12454646Smckusick beg = match(t[c1], "[^*]"); 12554646Smckusick end = match(t[c1], ";"); 12654646Smckusick printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n", 12754646Smckusick substr(t[c1], beg, end - beg), name); 12854725Sbostic }' < $SRC >> $HEADER 12954646Smckusick 13054725Sbostic# Print out header information for vnode_if.c. 13154725Sbosticcat << END_OF_LEADING_COMMENT > $CFILE 13254725Sbostic/* 13354727Sbostic * This file is produced automatically. 13454725Sbostic * Do not modify anything in here by hand. 13554725Sbostic * 136*55323Sheideman * Created from @(#)vnode_if.sh 7.4 (Berkeley) 07/17/92 13754725Sbostic */ 13854725Sbostic 13954725Sbostic#include <sys/param.h> 14054725Sbostic#include <sys/mount.h> 14154725Sbostic#include <sys/vnode.h> 14254725Sbostic 14354725Sbosticstruct vnodeop_desc vop_default_desc = { 14454725Sbostic 0, 14554725Sbostic "default", 14654725Sbostic 0, 14754725Sbostic NULL, 14854725Sbostic VDESC_NO_OFFSET, 14954725Sbostic VDESC_NO_OFFSET, 15054725Sbostic VDESC_NO_OFFSET, 151*55323Sheideman VDESC_NO_OFFSET, 15254725Sbostic NULL, 15354725Sbostic}; 15454725Sbostic 15554725SbosticEND_OF_LEADING_COMMENT 15654725Sbostic 15754725Sbostic# Awk script to take vnode_if.src and turn it into vnode_if.c. 158*55323Sheideman$AWK 'function kill_surrounding_ws (s) { 159*55323Sheideman sub (/^[ \t]*/, "", s); 160*55323Sheideman sub (/[ \t]*$/, "", s); 161*55323Sheideman return s; 162*55323Sheideman } 163*55323Sheideman 164*55323Sheideman function read_args() { 165*55323Sheideman numargs = 0; 166*55323Sheideman while (getline ln) { 167*55323Sheideman if (ln ~ /}/) { 168*55323Sheideman break; 169*55323Sheideman }; 170*55323Sheideman 171*55323Sheideman # Delete comments, if any. 172*55323Sheideman gsub (/\/\*.*\*\//, "", ln); 173*55323Sheideman 174*55323Sheideman # Delete leading/trailing space. 175*55323Sheideman ln = kill_surrounding_ws(ln); 176*55323Sheideman 177*55323Sheideman # Pick off direction. 178*55323Sheideman if (1 == sub(/^INOUT[ \t]+/, "", ln)) 179*55323Sheideman dir = "INOUT"; 180*55323Sheideman else if (1 == sub(/^IN[ \t]+/, "", ln)) 181*55323Sheideman dir = "IN"; 182*55323Sheideman else if (1 == sub(/^OUT[ \t]+/, "", ln)) 183*55323Sheideman dir = "OUT"; 184*55323Sheideman else 185*55323Sheideman bail("No IN/OUT direction for \"" ln "\"."); 186*55323Sheideman 187*55323Sheideman # check for "WILLRELE" 188*55323Sheideman if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) { 189*55323Sheideman rele = "WILLRELE"; 190*55323Sheideman } else { 191*55323Sheideman rele = "WONTRELE"; 192*55323Sheideman }; 193*55323Sheideman 194*55323Sheideman # kill trailing ; 195*55323Sheideman if (1 != sub (/;$/, "", ln)) { 196*55323Sheideman bail("Missing end-of-line ; in \"" ln "\"."); 197*55323Sheideman }; 198*55323Sheideman 199*55323Sheideman # pick off variable name 200*55323Sheideman if (!(i = match(ln, /[A-Za-z0-9_]+$/))) { 201*55323Sheideman bail("Missing var name \"a_foo\" in \"" ln "\"."); 202*55323Sheideman }; 203*55323Sheideman arg = substr (ln, i); 204*55323Sheideman # Want to <<substr(ln, i) = "";>>, but nawk cannot. 205*55323Sheideman # Hack around this. 206*55323Sheideman ln = substr(ln, 1, i-1); 207*55323Sheideman 208*55323Sheideman # what is left must be type 209*55323Sheideman # (put clean it up some) 210*55323Sheideman type = ln; 211*55323Sheideman gsub (/[ \t]+/, " ", type); # condense whitespace 212*55323Sheideman type = kill_surrounding_ws(type); 213*55323Sheideman 214*55323Sheideman # (boy this was easier in Perl) 215*55323Sheideman 216*55323Sheideman numargs++; 217*55323Sheideman dirs[numargs] = dir; 218*55323Sheideman reles[numargs] = rele; 219*55323Sheideman types[numargs] = type; 220*55323Sheideman args[numargs] = arg; 221*55323Sheideman }; 222*55323Sheideman } 223*55323Sheideman 224*55323Sheideman function generate_operation_vp_offsets() { 225*55323Sheideman printf ("int %s_vp_offsets[] = {\n", name); 226*55323Sheideman # as a side effect, figure out the releflags 227*55323Sheideman releflags = ""; 228*55323Sheideman vpnum = 0; 229*55323Sheideman for (i=1; i<=numargs; i++) { 230*55323Sheideman if (types[i] == "struct vnode *") { 231*55323Sheideman printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n", 232*55323Sheideman name, args[i]); 233*55323Sheideman if (reles[i] == "WILLRELE") { 234*55323Sheideman releflags = releflags "|VDESC_VP" vpnum "_WILLRELE"; 235*55323Sheideman }; 236*55323Sheideman vpnum++; 237*55323Sheideman }; 238*55323Sheideman }; 239*55323Sheideman sub (/^\|/, "", releflags); 240*55323Sheideman print "\tVDESC_NO_OFFSET"; 241*55323Sheideman print "};"; 242*55323Sheideman } 243*55323Sheideman 244*55323Sheideman function find_arg_with_type (type) { 245*55323Sheideman for (i=1; i<=numargs; i++) { 246*55323Sheideman if (types[i] == type) { 247*55323Sheideman return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")"; 248*55323Sheideman }; 249*55323Sheideman }; 250*55323Sheideman return "VDESC_NO_OFFSET"; 251*55323Sheideman } 252*55323Sheideman 253*55323Sheideman function generate_operation_desc() { 254*55323Sheideman printf ("struct vnodeop_desc %s_desc = {\n", name); 255*55323Sheideman # offset 256*55323Sheideman printf ("\t0,\n"); 257*55323Sheideman # printable name 258*55323Sheideman printf ("\t\"%s\",\n", name); 259*55323Sheideman # flags 260*55323Sheideman vppwillrele = ""; 261*55323Sheideman for (i=1; i<=numargs; i++) { 262*55323Sheideman if (types[i] == "struct vnode **" && 263*55323Sheideman (reles[i] == "WILLRELE")) { 264*55323Sheideman vppwillrele = "|VDESC_VPP_WILLRELE"; 265*55323Sheideman }; 266*55323Sheideman }; 267*55323Sheideman if (releflags == "") { 268*55323Sheideman printf ("\t0%s,\n", vppwillrele); 269*55323Sheideman } else { 270*55323Sheideman printf ("\t%s%s,\n", releflags, vppwillrele); 271*55323Sheideman }; 272*55323Sheideman # vp offsets 273*55323Sheideman printf ("\t%s_vp_offsets,\n", name); 274*55323Sheideman # vpp (if any) 275*55323Sheideman printf ("\t%s,\n", find_arg_with_type("struct vnode **")); 276*55323Sheideman # cred (if any) 277*55323Sheideman printf ("\t%s,\n", find_arg_with_type("struct ucred *")); 278*55323Sheideman # proc (if any) 279*55323Sheideman printf ("\t%s,\n", find_arg_with_type("struct proc *")); 280*55323Sheideman # componentname 281*55323Sheideman printf ("\t%s,\n", find_arg_with_type("struct componentname *")); 282*55323Sheideman # transport layer information 283*55323Sheideman printf ("\tNULL,\n};\n"); 284*55323Sheideman } 285*55323Sheideman 28654725Sbostic NF == 0 || $0 ~ "^#" { 28754725Sbostic next; 28854725Sbostic } 28954725Sbostic { 29054725Sbostic # get the function name 29154725Sbostic name = $1; 29254725Sbostic 29354725Sbostic # get the function arguments 294*55323Sheideman read_args(); 29554725Sbostic 29654725Sbostic # Print out the vop_F_vp_offsets structure. This all depends 29754725Sbostic # on naming conventions and nothing else. 298*55323Sheideman generate_operation_vp_offsets(); 29954725Sbostic 30054725Sbostic # Print out the vnodeop_desc structure. 301*55323Sheideman generate_operation_desc(); 30254725Sbostic 303*55323Sheideman printf "\n"; 30454725Sbostic 30554725Sbostic }' < $SRC >> $CFILE 30654646Smckusick# THINGS THAT DON'T WORK RIGHT YET. 30754646Smckusick# 30854646Smckusick# Two existing BSD vnodeops (bwrite and strategy) don't take any vnodes as 30954646Smckusick# arguments. This means that these operations can't function successfully 31054646Smckusick# through a bypass routine. 31154646Smckusick# 31254646Smckusick# Bwrite and strategy will be replaced when the VM page/buffer cache 31354646Smckusick# integration happens. 31454646Smckusick# 31554646Smckusick# To get around this problem for now we handle these ops as special cases. 31654646Smckusick 31754725Sbosticcat << END_OF_SPECIAL_CASES >> $HEADER 31854646Smckusick#include <sys/buf.h> 31954646Smckusickstruct vop_strategy_args { 32054646Smckusick struct vnodeop_desc *a_desc; 32154646Smckusick struct buf *a_bp; 32254646Smckusick}; 32354646Smckusickextern struct vnodeop_desc vop_strategy_desc; 32454646Smckusickstatic inline int VOP_STRATEGY(bp) 32554646Smckusick struct buf *bp; 32654646Smckusick{ 32754646Smckusick struct vop_strategy_args a; 32854646Smckusick 32954646Smckusick a.a_desc = VDESC(vop_strategy); 33054646Smckusick a.a_bp = bp; 33154646Smckusick return (VCALL((bp)->b_vp, VOFFSET(vop_strategy), &a)); 33254646Smckusick} 33354646Smckusick 33454646Smckusickstruct vop_bwrite_args { 33554646Smckusick struct vnodeop_desc *a_desc; 33654646Smckusick struct buf *a_bp; 33754646Smckusick}; 33854646Smckusickextern struct vnodeop_desc vop_bwrite_desc; 33954646Smckusickstatic inline int VOP_BWRITE(bp) 34054646Smckusick struct buf *bp; 34154646Smckusick{ 34254646Smckusick struct vop_bwrite_args a; 34354646Smckusick 34454646Smckusick a.a_desc = VDESC(vop_bwrite); 34554646Smckusick a.a_bp = bp; 34654646Smckusick return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a)); 34754646Smckusick} 34854646SmckusickEND_OF_SPECIAL_CASES 34954725Sbostic 35054725Sbosticcat << END_OF_SPECIAL_CASES >> $CFILE 35154725Sbosticint vop_strategy_vp_offsets[] = { 35254725Sbostic VDESC_NO_OFFSET 35354725Sbostic}; 35454725Sbosticstruct vnodeop_desc vop_strategy_desc = { 35554725Sbostic 0, 35654725Sbostic "vop_strategy", 35754725Sbostic 0, 35854725Sbostic vop_strategy_vp_offsets, 35954725Sbostic VDESC_NO_OFFSET, 36054725Sbostic VDESC_NO_OFFSET, 36154725Sbostic VDESC_NO_OFFSET, 362*55323Sheideman VDESC_NO_OFFSET, 36354725Sbostic NULL, 36454725Sbostic}; 36554725Sbosticint vop_bwrite_vp_offsets[] = { 36654725Sbostic VDESC_NO_OFFSET 36754725Sbostic}; 36854725Sbosticstruct vnodeop_desc vop_bwrite_desc = { 36954725Sbostic 0, 37054725Sbostic "vop_bwrite", 37154725Sbostic 0, 37254725Sbostic vop_bwrite_vp_offsets, 37354725Sbostic VDESC_NO_OFFSET, 37454725Sbostic VDESC_NO_OFFSET, 37554725Sbostic VDESC_NO_OFFSET, 376*55323Sheideman VDESC_NO_OFFSET, 37754725Sbostic NULL, 37854725Sbostic}; 37954725SbosticEND_OF_SPECIAL_CASES 38054725Sbostic 38154725Sbostic# Add the vfs_op_descs array to the C file. 382*55323Sheideman$AWK ' 38354725Sbostic BEGIN { 384*55323Sheideman printf("\nstruct vnodeop_desc *vfs_op_descs[] = {\n"); 38554725Sbostic printf("\t&vop_default_desc, /* MUST BE FIRST */\n"); 38654725Sbostic printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n"); 38754725Sbostic printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n"); 38854725Sbostic } 38954725Sbostic END { 39054725Sbostic printf("\tNULL\n};\n"); 39154725Sbostic } 39254725Sbostic NF == 0 || $0 ~ "^#" { 39354725Sbostic next; 39454725Sbostic } 39554725Sbostic { 39654725Sbostic # Get the function name. 39754725Sbostic printf("\t&%s_desc,\n", $1); 39854725Sbostic 39954725Sbostic # Skip the function arguments. 40054725Sbostic for (;;) { 40154725Sbostic if (getline <= 0) 40254725Sbostic exit 40354725Sbostic if ($0 ~ "^};") 40454725Sbostic break; 40554725Sbostic } 40654725Sbostic }' < $SRC >> $CFILE 407*55323Sheideman 408