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*54725Sbostic# @(#)vnode_if.sh 7.2 (Berkeley) 07/06/92 954646Smckusick# 1054646Smckusick 1154646Smckusick# Script to produce VFS front-end sugar. 12*54725Sbostic# 13*54725Sbostic# usage: vnode_if.sh srcfile 14*54725Sbostic# (where srcfile is currently /sys/kern/vnode_if.src) 15*54725Sbostic# 16*54725Sbostic# These awk scripts are not particularly well written, specifically they 17*54725Sbostic# don't use arrays well and figure out the same information repeatedly. 18*54725Sbostic# Please rewrite them if you actually understand how to use awk. Note, 19*54725Sbostic# they use nawk extensions. 2054646Smckusick 21*54725Sbosticif [ $# -ne 1 ] ; then 22*54725Sbostic printf 'usage: vnode_if.sh srcfile\n' 23*54725Sbostic exit 1 24*54725Sbosticfi 25*54725Sbostic 26*54725Sbostic# Name of the source file. 27*54725SbosticSRC=$1 28*54725Sbostic 29*54725Sbostic# Names of the created files. 30*54725SbosticCFILE=vnode_if.c 31*54725SbosticHEADER=vnode_if.h 32*54725Sbostic 33*54725Sbostic# Print out header information for vnode_if.h. 34*54725Sbosticcat << END_OF_LEADING_COMMENT > $HEADER 3554646Smckusick/* 3654646Smckusick * This file is produced by the script /sys/kern/vnode_if.sh. 3754646Smckusick * Do not modify anything in here by hand. 3854646Smckusick * 39*54725Sbostic * @(#)vnode_if.sh 7.2 (Berkeley) 07/06/92 4054646Smckusick */ 41*54725Sbostic 4254646Smckusickextern struct vnodeop_desc vop_default_desc; 4354646SmckusickEND_OF_LEADING_COMMENT 4454646Smckusick 4554646Smckusick# Awk script to take vnode_if.src and turn it into vnode_if.h. 4654646Smckusickawk ' 4754646Smckusick NF == 0 || $0 ~ "^#" { 4854646Smckusick next; 4954646Smckusick } 5054646Smckusick { 51*54725Sbostic # Get the function name. 5254646Smckusick name = $1; 5354646Smckusick uname = toupper(name); 5454646Smckusick 55*54725Sbostic # Get the function arguments. 5654646Smckusick for (c1 = 0;; ++c1) { 5754646Smckusick if (getline <= 0) 5854646Smckusick exit 5954646Smckusick if ($0 ~ "^};") 6054646Smckusick break; 6154646Smckusick a[c1] = $0; 6254646Smckusick } 6354646Smckusick 64*54725Sbostic # Print out the vop_F_args structure. 6554646Smckusick printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n", 6654646Smckusick name); 6754646Smckusick for (c2 = 0; c2 < c1; ++c2) { 6854646Smckusick c3 = split(a[c2], t); 6954646Smckusick printf("\t"); 7054646Smckusick for (c4 = 2; c4 < c3; ++c4) 7154646Smckusick printf("%s ", t[c4]); 7254646Smckusick beg = match(t[c3], "[^*]"); 7354646Smckusick printf("%sa_%s\n", 7454646Smckusick substr(t[c4], 0, beg - 1), substr(t[c4], beg)); 7554646Smckusick } 7654646Smckusick printf("};\n"); 7754646Smckusick 78*54725Sbostic # Print out extern declaration. 7954646Smckusick printf("extern struct vnodeop_desc %s_desc;\n", name); 8054646Smckusick 81*54725Sbostic # Print out inline struct. 8254646Smckusick printf("static inline int %s(", uname); 8354646Smckusick sep = ", "; 8454646Smckusick for (c2 = 0; c2 < c1; ++c2) { 8554646Smckusick if (c2 == c1 - 1) 8654646Smckusick sep = ")\n"; 8754646Smckusick c3 = split(a[c2], t); 8854646Smckusick beg = match(t[c3], "[^*]"); 8954646Smckusick end = match(t[c3], ";"); 9054646Smckusick printf("%s%s", substr(t[c3], beg, end - beg), sep); 9154646Smckusick } 9254646Smckusick for (c2 = 0; c2 < c1; ++c2) { 9354646Smckusick c3 = split(a[c2], t); 9454646Smckusick printf("\t"); 9554646Smckusick for (c4 = 2; c4 < c3; ++c4) 9654646Smckusick printf("%s ", t[c4]); 9754646Smckusick beg = match(t[c3], "[^*]"); 9854646Smckusick printf("%s%s\n", 9954646Smckusick substr(t[c4], 0, beg - 1), substr(t[c4], beg)); 10054646Smckusick } 10154646Smckusick printf("{\n\tstruct %s_args a;\n\n", name); 10254646Smckusick printf("\ta.a_desc = VDESC(%s);\n", name); 10354646Smckusick for (c2 = 0; c2 < c1; ++c2) { 10454646Smckusick c3 = split(a[c2], t); 10554646Smckusick printf("\t"); 10654646Smckusick beg = match(t[c3], "[^*]"); 10754646Smckusick end = match(t[c3], ";"); 10854646Smckusick printf("a.a_%s = %s\n", 10954646Smckusick substr(t[c3], beg, end - beg), substr(t[c3], beg)); 11054646Smckusick } 11154646Smckusick c1 = split(a[0], t); 11254646Smckusick beg = match(t[c1], "[^*]"); 11354646Smckusick end = match(t[c1], ";"); 11454646Smckusick printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n", 11554646Smckusick substr(t[c1], beg, end - beg), name); 116*54725Sbostic }' < $SRC >> $HEADER 11754646Smckusick 118*54725Sbostic# Print out header information for vnode_if.c. 119*54725Sbosticcat << END_OF_LEADING_COMMENT > $CFILE 120*54725Sbostic/* 121*54725Sbostic * This file is produced by the script /sys/kern/vnode_if.sh. 122*54725Sbostic * Do not modify anything in here by hand. 123*54725Sbostic * 124*54725Sbostic * @(#)vnode_if.sh 7.2 (Berkeley) 07/06/92 125*54725Sbostic */ 126*54725Sbostic 127*54725Sbostic#include <sys/param.h> 128*54725Sbostic#include <sys/mount.h> 129*54725Sbostic#include <sys/vnode.h> 130*54725Sbostic 131*54725Sbosticstruct vnodeop_desc vop_default_desc = { 132*54725Sbostic 0, 133*54725Sbostic "default", 134*54725Sbostic 0, 135*54725Sbostic NULL, 136*54725Sbostic VDESC_NO_OFFSET, 137*54725Sbostic VDESC_NO_OFFSET, 138*54725Sbostic VDESC_NO_OFFSET, 139*54725Sbostic NULL, 140*54725Sbostic}; 141*54725Sbostic 142*54725SbosticEND_OF_LEADING_COMMENT 143*54725Sbostic 144*54725Sbostic# Awk script to take vnode_if.src and turn it into vnode_if.c. 145*54725Sbosticawk ' 146*54725Sbostic NF == 0 || $0 ~ "^#" { 147*54725Sbostic next; 148*54725Sbostic } 149*54725Sbostic { 150*54725Sbostic # get the function name 151*54725Sbostic name = $1; 152*54725Sbostic 153*54725Sbostic # get the function arguments 154*54725Sbostic for (c1 = 0;; ++c1) { 155*54725Sbostic if (getline <= 0) 156*54725Sbostic exit 157*54725Sbostic if ($0 ~ "^};") 158*54725Sbostic break; 159*54725Sbostic a[c1] = $0; 160*54725Sbostic } 161*54725Sbostic 162*54725Sbostic # Print out the vop_F_vp_offsets structure. This all depends 163*54725Sbostic # on naming conventions and nothing else. 164*54725Sbostic printf("int %s_vp_offsets[] = {\n", name); 165*54725Sbostic for (c2 = 0; c2 < c1; ++c2) { 166*54725Sbostic c3 = split(a[c2], t); 167*54725Sbostic if (c3 != 4 || t[1] !~ /^IN$/ || t[2] !~ /^struct$/ || 168*54725Sbostic t[3] !~ /^vnode$/ || t[4] !~ /.*vp;$/) 169*54725Sbostic continue; 170*54725Sbostic beg = match(t[c3], "[^*]"); 171*54725Sbostic end = match(t[c3], ";"); 172*54725Sbostic printf("\tVOPARG_OFFSETOF(struct %s_args, a_%s),\n", 173*54725Sbostic name, substr(t[4], beg, end - beg)); 174*54725Sbostic } 175*54725Sbostic printf("\tVDESC_NO_OFFSET\n};\n"); 176*54725Sbostic 177*54725Sbostic # Print out the vnodeop_desc structure. 178*54725Sbostic printf("struct vnodeop_desc %s_desc = {\n", name); 179*54725Sbostic printf("\t0,\n\t\"%s\",\n\t0,\n\t%s_vp_offsets,\n", name, name); 180*54725Sbostic 181*54725Sbostic # Print out return vpp entry, if any. 182*54725Sbostic for (found = c2 = 0; c2 < c1; ++c2) { 183*54725Sbostic c3 = split(a[c2], t); 184*54725Sbostic if (c3 != 4 || t[1] !~ /^OUT$/ || t[2] !~ /^struct$/ || 185*54725Sbostic t[3] !~ /^vnode$/) 186*54725Sbostic continue; 187*54725Sbostic printf("\tVOPARG_OFFSETOF(struct %s_args, a_vpp),\n", 188*54725Sbostic name); 189*54725Sbostic found = 1; 190*54725Sbostic break; 191*54725Sbostic } 192*54725Sbostic if (found == 0) 193*54725Sbostic printf("\tVDESC_NO_OFFSET,\n"); 194*54725Sbostic 195*54725Sbostic # Print out cred entry, if any. 196*54725Sbostic for (found = c2 = 0; c2 < c1; ++c2) { 197*54725Sbostic c3 = split(a[c2], t); 198*54725Sbostic if (c3 != 4 || t[1] !~ /^IN$/ || t[2] !~ /^struct$/ || 199*54725Sbostic t[3] !~ /^ucred$/) 200*54725Sbostic continue; 201*54725Sbostic printf("\tVOPARG_OFFSETOF(struct %s_args, a_cred),\n", 202*54725Sbostic name); 203*54725Sbostic found = 1; 204*54725Sbostic break; 205*54725Sbostic } 206*54725Sbostic if (found == 0) 207*54725Sbostic printf("\tVDESC_NO_OFFSET,\n"); 208*54725Sbostic 209*54725Sbostic # Print out proc entry, if any. 210*54725Sbostic for (found = c2 = 0; c2 < c1; ++c2) { 211*54725Sbostic c3 = split(a[c2], t); 212*54725Sbostic if (c3 != 4 || t[1] !~ /^IN$/ || t[2] !~ /^struct$/ || 213*54725Sbostic t[3] !~ /^proc$/) 214*54725Sbostic continue; 215*54725Sbostic printf("\tVOPARG_OFFSETOF(struct %s_args, a_p),\n", 216*54725Sbostic name); 217*54725Sbostic found = 1; 218*54725Sbostic break; 219*54725Sbostic } 220*54725Sbostic if (found == 0) 221*54725Sbostic printf("\tVDESC_NO_OFFSET,\n"); 222*54725Sbostic printf("\tNULL,\n};\n"); 223*54725Sbostic }' < $SRC >> $CFILE 224*54725Sbostic 22554646Smckusick# THINGS THAT DON'T WORK RIGHT YET. 22654646Smckusick# 22754646Smckusick# Two existing BSD vnodeops (bwrite and strategy) don't take any vnodes as 22854646Smckusick# arguments. This means that these operations can't function successfully 22954646Smckusick# through a bypass routine. 23054646Smckusick# 23154646Smckusick# Bwrite and strategy will be replaced when the VM page/buffer cache 23254646Smckusick# integration happens. 23354646Smckusick# 23454646Smckusick# To get around this problem for now we handle these ops as special cases. 23554646Smckusick 236*54725Sbosticcat << END_OF_SPECIAL_CASES >> $HEADER 23754646Smckusick#include <sys/buf.h> 23854646Smckusickstruct vop_strategy_args { 23954646Smckusick struct vnodeop_desc *a_desc; 24054646Smckusick struct buf *a_bp; 24154646Smckusick}; 24254646Smckusickextern struct vnodeop_desc vop_strategy_desc; 24354646Smckusickstatic inline int VOP_STRATEGY(bp) 24454646Smckusick struct buf *bp; 24554646Smckusick{ 24654646Smckusick struct vop_strategy_args a; 24754646Smckusick 24854646Smckusick a.a_desc = VDESC(vop_strategy); 24954646Smckusick a.a_bp = bp; 25054646Smckusick return (VCALL((bp)->b_vp, VOFFSET(vop_strategy), &a)); 25154646Smckusick} 25254646Smckusick 25354646Smckusickstruct vop_bwrite_args { 25454646Smckusick struct vnodeop_desc *a_desc; 25554646Smckusick struct buf *a_bp; 25654646Smckusick}; 25754646Smckusickextern struct vnodeop_desc vop_bwrite_desc; 25854646Smckusickstatic inline int VOP_BWRITE(bp) 25954646Smckusick struct buf *bp; 26054646Smckusick{ 26154646Smckusick struct vop_bwrite_args a; 26254646Smckusick 26354646Smckusick a.a_desc = VDESC(vop_bwrite); 26454646Smckusick a.a_bp = bp; 26554646Smckusick return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a)); 26654646Smckusick} 26754646SmckusickEND_OF_SPECIAL_CASES 268*54725Sbostic 269*54725Sbosticcat << END_OF_SPECIAL_CASES >> $CFILE 270*54725Sbosticint vop_strategy_vp_offsets[] = { 271*54725Sbostic VDESC_NO_OFFSET 272*54725Sbostic}; 273*54725Sbosticstruct vnodeop_desc vop_strategy_desc = { 274*54725Sbostic 0, 275*54725Sbostic "vop_strategy", 276*54725Sbostic 0, 277*54725Sbostic vop_strategy_vp_offsets, 278*54725Sbostic VDESC_NO_OFFSET, 279*54725Sbostic VDESC_NO_OFFSET, 280*54725Sbostic VDESC_NO_OFFSET, 281*54725Sbostic NULL, 282*54725Sbostic}; 283*54725Sbosticint vop_bwrite_vp_offsets[] = { 284*54725Sbostic VDESC_NO_OFFSET 285*54725Sbostic}; 286*54725Sbosticstruct vnodeop_desc vop_bwrite_desc = { 287*54725Sbostic 0, 288*54725Sbostic "vop_bwrite", 289*54725Sbostic 0, 290*54725Sbostic vop_bwrite_vp_offsets, 291*54725Sbostic VDESC_NO_OFFSET, 292*54725Sbostic VDESC_NO_OFFSET, 293*54725Sbostic VDESC_NO_OFFSET, 294*54725Sbostic NULL, 295*54725Sbostic}; 296*54725SbosticEND_OF_SPECIAL_CASES 297*54725Sbostic 298*54725Sbostic# Add the vfs_op_descs array to the C file. 299*54725Sbosticawk ' 300*54725Sbostic BEGIN { 301*54725Sbostic printf("struct vnodeop_desc *vfs_op_descs[] = {\n"); 302*54725Sbostic printf("\t&vop_default_desc, /* MUST BE FIRST */\n"); 303*54725Sbostic printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n"); 304*54725Sbostic printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n"); 305*54725Sbostic } 306*54725Sbostic END { 307*54725Sbostic printf("\tNULL\n};\n"); 308*54725Sbostic } 309*54725Sbostic NF == 0 || $0 ~ "^#" { 310*54725Sbostic next; 311*54725Sbostic } 312*54725Sbostic { 313*54725Sbostic # Get the function name. 314*54725Sbostic printf("\t&%s_desc,\n", $1); 315*54725Sbostic 316*54725Sbostic # Skip the function arguments. 317*54725Sbostic for (;;) { 318*54725Sbostic if (getline <= 0) 319*54725Sbostic exit 320*54725Sbostic if ($0 ~ "^};") 321*54725Sbostic break; 322*54725Sbostic } 323*54725Sbostic }' < $SRC >> $CFILE 324