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