xref: /csrg-svn/sys/kern/vnode_if.sh (revision 55323)
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