xref: /csrg-svn/sys/kern/vnode_if.sh (revision 63176)
154646Smckusick#!/bin/sh -
254646Smckusick#
3*63176Sbostic# Copyright (c) 1992, 1993
4*63176Sbostic#	The Regents of the University of California.  All rights reserved.
554646Smckusick#
654646Smckusick# %sccs.include.redist.sh%
754646Smckusick#
8*63176Sbostic#	@(#)vnode_if.sh	8.1 (Berkeley) 06/10/93
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,
1955323Sheideman# they use nawk extensions and gawk's toupper.
2054646Smckusick
2154725Sbosticif [ $# -ne 1 ] ; then
2255323Sheideman	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
3355323Sheideman# Awk program (must support nawk extensions and gawk's "toupper")
3455323Sheideman# Use "awk" at Berkeley, "gawk" elsewhere.
3555323SheidemanAWK=awk
3655323Sheideman
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*63176Sbostic * Created from @(#)vnode_if.sh	8.1 (Berkeley) 06/10/93
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.
5055323Sheideman$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");
7455323Sheideman			if (t[2] ~ "WILLRELE")
7555323Sheideman				c4 = 3;
7655323Sheideman			else
7755323Sheideman				c4 = 2;
7855323Sheideman			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");
10355323Sheideman			if (t[2] ~ "WILLRELE")
10455323Sheideman				c4 = 3;
10555323Sheideman			else
10655323Sheideman				c4 = 2;
10755323Sheideman			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*63176Sbostic * Created from @(#)vnode_if.sh	8.1 (Berkeley) 06/10/93
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,
15155323Sheideman	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.
15855323Sheideman$AWK 'function kill_surrounding_ws (s) {
15955323Sheideman		sub (/^[ \t]*/, "", s);
16055323Sheideman		sub (/[ \t]*$/, "", s);
16155323Sheideman		return s;
16255323Sheideman	}
16355323Sheideman
16455323Sheideman	function read_args() {
16555323Sheideman		numargs = 0;
16655323Sheideman		while (getline ln) {
16755323Sheideman			if (ln ~ /}/) {
16855323Sheideman				break;
16955323Sheideman			};
17055323Sheideman
17155323Sheideman			# Delete comments, if any.
17255323Sheideman			gsub (/\/\*.*\*\//, "", ln);
17355323Sheideman
17455323Sheideman			# Delete leading/trailing space.
17555323Sheideman			ln = kill_surrounding_ws(ln);
17655323Sheideman
17755323Sheideman			# Pick off direction.
17855323Sheideman			if (1 == sub(/^INOUT[ \t]+/, "", ln))
17955323Sheideman				dir = "INOUT";
18055323Sheideman			else if (1 == sub(/^IN[ \t]+/, "", ln))
18155323Sheideman				dir = "IN";
18255323Sheideman			else if (1 == sub(/^OUT[ \t]+/, "", ln))
18355323Sheideman				dir = "OUT";
18455323Sheideman			else
18555323Sheideman				bail("No IN/OUT direction for \"" ln "\".");
18655323Sheideman
18755323Sheideman			# check for "WILLRELE"
18855323Sheideman			if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) {
18955323Sheideman				rele = "WILLRELE";
19055323Sheideman			} else {
19155323Sheideman				rele = "WONTRELE";
19255323Sheideman			};
19355323Sheideman
19455323Sheideman			# kill trailing ;
19555323Sheideman			if (1 != sub (/;$/, "", ln)) {
19655323Sheideman				bail("Missing end-of-line ; in \"" ln "\".");
19755323Sheideman			};
19855323Sheideman
19955323Sheideman			# pick off variable name
20055323Sheideman			if (!(i = match(ln, /[A-Za-z0-9_]+$/))) {
20155323Sheideman				bail("Missing var name \"a_foo\" in \"" ln "\".");
20255323Sheideman			};
20355323Sheideman			arg = substr (ln, i);
20455323Sheideman			# Want to <<substr(ln, i) = "";>>, but nawk cannot.
20555323Sheideman			# Hack around this.
20655323Sheideman			ln = substr(ln, 1, i-1);
20755323Sheideman
20855323Sheideman			# what is left must be type
20955323Sheideman			# (put clean it up some)
21055323Sheideman			type = ln;
21155323Sheideman			gsub (/[ \t]+/, " ", type);   # condense whitespace
21255323Sheideman			type = kill_surrounding_ws(type);
21355323Sheideman
21455323Sheideman			# (boy this was easier in Perl)
21555323Sheideman
21655323Sheideman			numargs++;
21755323Sheideman			dirs[numargs] = dir;
21855323Sheideman			reles[numargs] = rele;
21955323Sheideman			types[numargs] = type;
22055323Sheideman			args[numargs] = arg;
22155323Sheideman		};
22255323Sheideman	}
22355323Sheideman
22455323Sheideman	function generate_operation_vp_offsets() {
22555323Sheideman		printf ("int %s_vp_offsets[] = {\n", name);
22655323Sheideman		# as a side effect, figure out the releflags
22755323Sheideman		releflags = "";
22855323Sheideman		vpnum = 0;
22955323Sheideman		for (i=1; i<=numargs; i++) {
23055323Sheideman			if (types[i] == "struct vnode *") {
23155323Sheideman				printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
23255323Sheideman					name, args[i]);
23355323Sheideman				if (reles[i] == "WILLRELE") {
23455323Sheideman					releflags = releflags "|VDESC_VP" vpnum "_WILLRELE";
23555323Sheideman				};
23655323Sheideman				vpnum++;
23755323Sheideman			};
23855323Sheideman		};
23955323Sheideman		sub (/^\|/, "", releflags);
24055323Sheideman		print "\tVDESC_NO_OFFSET";
24155323Sheideman		print "};";
24255323Sheideman	}
24355323Sheideman
24455323Sheideman	function find_arg_with_type (type) {
24555323Sheideman		for (i=1; i<=numargs; i++) {
24655323Sheideman			if (types[i] == type) {
24755323Sheideman				return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")";
24855323Sheideman			};
24955323Sheideman		};
25055323Sheideman		return "VDESC_NO_OFFSET";
25155323Sheideman	}
25255323Sheideman
25355323Sheideman	function generate_operation_desc() {
25455323Sheideman		printf ("struct vnodeop_desc %s_desc = {\n", name);
25555323Sheideman		# offset
25655323Sheideman		printf ("\t0,\n");
25755323Sheideman		# printable name
25855323Sheideman		printf ("\t\"%s\",\n", name);
25955323Sheideman		# flags
26055323Sheideman		vppwillrele = "";
26155323Sheideman		for (i=1; i<=numargs; i++) {
26255323Sheideman			if (types[i] == "struct vnode **" &&
26355323Sheideman				(reles[i] == "WILLRELE")) {
26455323Sheideman				vppwillrele = "|VDESC_VPP_WILLRELE";
26555323Sheideman			};
26655323Sheideman		};
26755323Sheideman		if (releflags == "") {
26855323Sheideman			printf ("\t0%s,\n", vppwillrele);
26955323Sheideman		} else {
27055323Sheideman			printf ("\t%s%s,\n", releflags, vppwillrele);
27155323Sheideman		};
27255323Sheideman		# vp offsets
27355323Sheideman		printf ("\t%s_vp_offsets,\n", name);
27455323Sheideman		# vpp (if any)
27555323Sheideman		printf ("\t%s,\n", find_arg_with_type("struct vnode **"));
27655323Sheideman		# cred (if any)
27755323Sheideman		printf ("\t%s,\n", find_arg_with_type("struct ucred *"));
27855323Sheideman		# proc (if any)
27955323Sheideman		printf ("\t%s,\n", find_arg_with_type("struct proc *"));
28055323Sheideman		# componentname
28155323Sheideman		printf ("\t%s,\n", find_arg_with_type("struct componentname *"));
28255323Sheideman		# transport layer information
28355323Sheideman		printf ("\tNULL,\n};\n");
28455323Sheideman	}
28555323Sheideman
28654725Sbostic	NF == 0 || $0 ~ "^#" {
28754725Sbostic		next;
28854725Sbostic	}
28954725Sbostic	{
29054725Sbostic		# get the function name
29154725Sbostic		name = $1;
29254725Sbostic
29354725Sbostic		# get the function arguments
29455323Sheideman		read_args();
29554725Sbostic
29654725Sbostic		# Print out the vop_F_vp_offsets structure.  This all depends
29754725Sbostic		# on naming conventions and nothing else.
29855323Sheideman		generate_operation_vp_offsets();
29954725Sbostic
30054725Sbostic		# Print out the vnodeop_desc structure.
30155323Sheideman		generate_operation_desc();
30254725Sbostic
30355323Sheideman		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,
36255323Sheideman	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,
37655323Sheideman	VDESC_NO_OFFSET,
37754725Sbostic	NULL,
37854725Sbostic};
37954725SbosticEND_OF_SPECIAL_CASES
38054725Sbostic
38154725Sbostic# Add the vfs_op_descs array to the C file.
38255323Sheideman$AWK '
38354725Sbostic	BEGIN {
38455323Sheideman		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
40755323Sheideman
408