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*54727Sbostic# @(#)vnode_if.sh 7.3 (Berkeley) 07/06/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, 1954725Sbostic# they use nawk extensions. 2054646Smckusick 2154725Sbosticif [ $# -ne 1 ] ; then 2254725Sbostic printf 'usage: vnode_if.sh srcfile\n' 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 3354725Sbostic# Print out header information for vnode_if.h. 3454725Sbosticcat << END_OF_LEADING_COMMENT > $HEADER 3554646Smckusick/* 36*54727Sbostic * This file is produced automatically. 3754646Smckusick * Do not modify anything in here by hand. 3854646Smckusick * 39*54727Sbostic * Created from @(#)vnode_if.sh 7.3 (Berkeley) 07/06/92 4054646Smckusick */ 4154725Sbostic 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 { 5154725Sbostic # Get the function name. 5254646Smckusick name = $1; 5354646Smckusick uname = toupper(name); 5454646Smckusick 5554725Sbostic # 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 6454725Sbostic # 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 7854725Sbostic # Print out extern declaration. 7954646Smckusick printf("extern struct vnodeop_desc %s_desc;\n", name); 8054646Smckusick 8154725Sbostic # 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); 11654725Sbostic }' < $SRC >> $HEADER 11754646Smckusick 11854725Sbostic# Print out header information for vnode_if.c. 11954725Sbosticcat << END_OF_LEADING_COMMENT > $CFILE 12054725Sbostic/* 121*54727Sbostic * This file is produced automatically. 12254725Sbostic * Do not modify anything in here by hand. 12354725Sbostic * 124*54727Sbostic * Created from @(#)vnode_if.sh 7.3 (Berkeley) 07/06/92 12554725Sbostic */ 12654725Sbostic 12754725Sbostic#include <sys/param.h> 12854725Sbostic#include <sys/mount.h> 12954725Sbostic#include <sys/vnode.h> 13054725Sbostic 13154725Sbosticstruct vnodeop_desc vop_default_desc = { 13254725Sbostic 0, 13354725Sbostic "default", 13454725Sbostic 0, 13554725Sbostic NULL, 13654725Sbostic VDESC_NO_OFFSET, 13754725Sbostic VDESC_NO_OFFSET, 13854725Sbostic VDESC_NO_OFFSET, 13954725Sbostic NULL, 14054725Sbostic}; 14154725Sbostic 14254725SbosticEND_OF_LEADING_COMMENT 14354725Sbostic 14454725Sbostic# Awk script to take vnode_if.src and turn it into vnode_if.c. 14554725Sbosticawk ' 14654725Sbostic NF == 0 || $0 ~ "^#" { 14754725Sbostic next; 14854725Sbostic } 14954725Sbostic { 15054725Sbostic # get the function name 15154725Sbostic name = $1; 15254725Sbostic 15354725Sbostic # get the function arguments 15454725Sbostic for (c1 = 0;; ++c1) { 15554725Sbostic if (getline <= 0) 15654725Sbostic exit 15754725Sbostic if ($0 ~ "^};") 15854725Sbostic break; 15954725Sbostic a[c1] = $0; 16054725Sbostic } 16154725Sbostic 16254725Sbostic # Print out the vop_F_vp_offsets structure. This all depends 16354725Sbostic # on naming conventions and nothing else. 16454725Sbostic printf("int %s_vp_offsets[] = {\n", name); 16554725Sbostic for (c2 = 0; c2 < c1; ++c2) { 16654725Sbostic c3 = split(a[c2], t); 16754725Sbostic if (c3 != 4 || t[1] !~ /^IN$/ || t[2] !~ /^struct$/ || 16854725Sbostic t[3] !~ /^vnode$/ || t[4] !~ /.*vp;$/) 16954725Sbostic continue; 17054725Sbostic beg = match(t[c3], "[^*]"); 17154725Sbostic end = match(t[c3], ";"); 17254725Sbostic printf("\tVOPARG_OFFSETOF(struct %s_args, a_%s),\n", 17354725Sbostic name, substr(t[4], beg, end - beg)); 17454725Sbostic } 17554725Sbostic printf("\tVDESC_NO_OFFSET\n};\n"); 17654725Sbostic 17754725Sbostic # Print out the vnodeop_desc structure. 17854725Sbostic printf("struct vnodeop_desc %s_desc = {\n", name); 17954725Sbostic printf("\t0,\n\t\"%s\",\n\t0,\n\t%s_vp_offsets,\n", name, name); 18054725Sbostic 18154725Sbostic # Print out return vpp entry, if any. 18254725Sbostic for (found = c2 = 0; c2 < c1; ++c2) { 18354725Sbostic c3 = split(a[c2], t); 18454725Sbostic if (c3 != 4 || t[1] !~ /^OUT$/ || t[2] !~ /^struct$/ || 18554725Sbostic t[3] !~ /^vnode$/) 18654725Sbostic continue; 18754725Sbostic printf("\tVOPARG_OFFSETOF(struct %s_args, a_vpp),\n", 18854725Sbostic name); 18954725Sbostic found = 1; 19054725Sbostic break; 19154725Sbostic } 19254725Sbostic if (found == 0) 19354725Sbostic printf("\tVDESC_NO_OFFSET,\n"); 19454725Sbostic 19554725Sbostic # Print out cred entry, if any. 19654725Sbostic for (found = c2 = 0; c2 < c1; ++c2) { 19754725Sbostic c3 = split(a[c2], t); 19854725Sbostic if (c3 != 4 || t[1] !~ /^IN$/ || t[2] !~ /^struct$/ || 19954725Sbostic t[3] !~ /^ucred$/) 20054725Sbostic continue; 20154725Sbostic printf("\tVOPARG_OFFSETOF(struct %s_args, a_cred),\n", 20254725Sbostic name); 20354725Sbostic found = 1; 20454725Sbostic break; 20554725Sbostic } 20654725Sbostic if (found == 0) 20754725Sbostic printf("\tVDESC_NO_OFFSET,\n"); 20854725Sbostic 20954725Sbostic # Print out proc entry, if any. 21054725Sbostic for (found = c2 = 0; c2 < c1; ++c2) { 21154725Sbostic c3 = split(a[c2], t); 21254725Sbostic if (c3 != 4 || t[1] !~ /^IN$/ || t[2] !~ /^struct$/ || 21354725Sbostic t[3] !~ /^proc$/) 21454725Sbostic continue; 21554725Sbostic printf("\tVOPARG_OFFSETOF(struct %s_args, a_p),\n", 21654725Sbostic name); 21754725Sbostic found = 1; 21854725Sbostic break; 21954725Sbostic } 22054725Sbostic if (found == 0) 22154725Sbostic printf("\tVDESC_NO_OFFSET,\n"); 22254725Sbostic printf("\tNULL,\n};\n"); 22354725Sbostic }' < $SRC >> $CFILE 22454725Sbostic 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 23654725Sbosticcat << 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 26854725Sbostic 26954725Sbosticcat << END_OF_SPECIAL_CASES >> $CFILE 27054725Sbosticint vop_strategy_vp_offsets[] = { 27154725Sbostic VDESC_NO_OFFSET 27254725Sbostic}; 27354725Sbosticstruct vnodeop_desc vop_strategy_desc = { 27454725Sbostic 0, 27554725Sbostic "vop_strategy", 27654725Sbostic 0, 27754725Sbostic vop_strategy_vp_offsets, 27854725Sbostic VDESC_NO_OFFSET, 27954725Sbostic VDESC_NO_OFFSET, 28054725Sbostic VDESC_NO_OFFSET, 28154725Sbostic NULL, 28254725Sbostic}; 28354725Sbosticint vop_bwrite_vp_offsets[] = { 28454725Sbostic VDESC_NO_OFFSET 28554725Sbostic}; 28654725Sbosticstruct vnodeop_desc vop_bwrite_desc = { 28754725Sbostic 0, 28854725Sbostic "vop_bwrite", 28954725Sbostic 0, 29054725Sbostic vop_bwrite_vp_offsets, 29154725Sbostic VDESC_NO_OFFSET, 29254725Sbostic VDESC_NO_OFFSET, 29354725Sbostic VDESC_NO_OFFSET, 29454725Sbostic NULL, 29554725Sbostic}; 29654725SbosticEND_OF_SPECIAL_CASES 29754725Sbostic 29854725Sbostic# Add the vfs_op_descs array to the C file. 29954725Sbosticawk ' 30054725Sbostic BEGIN { 30154725Sbostic printf("struct vnodeop_desc *vfs_op_descs[] = {\n"); 30254725Sbostic printf("\t&vop_default_desc, /* MUST BE FIRST */\n"); 30354725Sbostic printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n"); 30454725Sbostic printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n"); 30554725Sbostic } 30654725Sbostic END { 30754725Sbostic printf("\tNULL\n};\n"); 30854725Sbostic } 30954725Sbostic NF == 0 || $0 ~ "^#" { 31054725Sbostic next; 31154725Sbostic } 31254725Sbostic { 31354725Sbostic # Get the function name. 31454725Sbostic printf("\t&%s_desc,\n", $1); 31554725Sbostic 31654725Sbostic # Skip the function arguments. 31754725Sbostic for (;;) { 31854725Sbostic if (getline <= 0) 31954725Sbostic exit 32054725Sbostic if ($0 ~ "^};") 32154725Sbostic break; 32254725Sbostic } 32354725Sbostic }' < $SRC >> $CFILE 324