xref: /f-stack/freebsd/tools/vnode_if.awk (revision 22ce4aff)
1a9643ea8Slogwang#!/usr/bin/awk -f
2a9643ea8Slogwang
3a9643ea8Slogwang#-
4*22ce4affSfengbojiang# SPDX-License-Identifier: BSD-3-Clause
5*22ce4affSfengbojiang#
6a9643ea8Slogwang# Copyright (c) 1992, 1993
7a9643ea8Slogwang#	The Regents of the University of California.  All rights reserved.
8a9643ea8Slogwang#
9a9643ea8Slogwang# Redistribution and use in source and binary forms, with or without
10a9643ea8Slogwang# modification, are permitted provided that the following conditions
11a9643ea8Slogwang# are met:
12a9643ea8Slogwang# 1. Redistributions of source code must retain the above copyright
13a9643ea8Slogwang#    notice, this list of conditions and the following disclaimer.
14a9643ea8Slogwang# 2. Redistributions in binary form must reproduce the above copyright
15a9643ea8Slogwang#    notice, this list of conditions and the following disclaimer in the
16a9643ea8Slogwang#    documentation and/or other materials provided with the distribution.
17*22ce4affSfengbojiang# 3. Neither the name of the University nor the names of its contributors
18a9643ea8Slogwang#    may be used to endorse or promote products derived from this software
19a9643ea8Slogwang#    without specific prior written permission.
20a9643ea8Slogwang#
21a9643ea8Slogwang# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22a9643ea8Slogwang# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23a9643ea8Slogwang# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24a9643ea8Slogwang# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25a9643ea8Slogwang# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26a9643ea8Slogwang# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27a9643ea8Slogwang# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28a9643ea8Slogwang# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29a9643ea8Slogwang# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30a9643ea8Slogwang# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31a9643ea8Slogwang# SUCH DAMAGE.
32a9643ea8Slogwang
33a9643ea8Slogwang#
34a9643ea8Slogwang#	@(#)vnode_if.sh	8.1 (Berkeley) 6/10/93
35a9643ea8Slogwang# $FreeBSD$
36a9643ea8Slogwang#
37a9643ea8Slogwang# Script to produce VFS front-end sugar.
38a9643ea8Slogwang#
39a9643ea8Slogwang# usage: vnode_if.awk <srcfile> [-c | -h | -p | -q]
40a9643ea8Slogwang#	(where <srcfile> is currently /sys/kern/vnode_if.src)
41a9643ea8Slogwang#	The source file must have a .src extension
42a9643ea8Slogwang#
43a9643ea8Slogwang
44a9643ea8Slogwangfunction usage()
45a9643ea8Slogwang{
46a9643ea8Slogwang	print "usage: vnode_if.awk <srcfile> [-c|-h|-p|-q]";
47a9643ea8Slogwang	exit 1;
48a9643ea8Slogwang}
49a9643ea8Slogwang
50a9643ea8Slogwangfunction die(msg, what)
51a9643ea8Slogwang{
52a9643ea8Slogwang	printf srcfile "(" fnr "): " > "/dev/stderr";
53a9643ea8Slogwang	printf msg "\n", what > "/dev/stderr";
54a9643ea8Slogwang	exit 1;
55a9643ea8Slogwang}
56a9643ea8Slogwang
57a9643ea8Slogwangfunction t_spc(type)
58a9643ea8Slogwang{
59a9643ea8Slogwang	# Append a space if the type is not a pointer
60a9643ea8Slogwang	return (type ~ /\*$/) ? type : type " ";
61a9643ea8Slogwang}
62a9643ea8Slogwang
63a9643ea8Slogwang# These are just for convenience ...
64a9643ea8Slogwangfunction printc(s) {print s > cfile;}
65a9643ea8Slogwangfunction printh(s) {print s > hfile;}
66a9643ea8Slogwangfunction printp(s) {print s > pfile;}
67a9643ea8Slogwangfunction printq(s) {print s > qfile;}
68a9643ea8Slogwang
69a9643ea8Slogwangfunction add_debug_code(name, arg, pos, ind)
70a9643ea8Slogwang{
71a9643ea8Slogwang	if (arg == "vpp")
72a9643ea8Slogwang		star = "*";
73a9643ea8Slogwang	else
74a9643ea8Slogwang		star = "";
75a9643ea8Slogwang	if (lockdata[name, arg, pos] && (lockdata[name, arg, pos] != "-")) {
76a9643ea8Slogwang		printc(ind"ASSERT_VI_UNLOCKED("star"a->a_"arg", \""uname"\");");
77a9643ea8Slogwang		# Add assertions for locking
78a9643ea8Slogwang		if (lockdata[name, arg, pos] == "L")
79a9643ea8Slogwang			printc(ind"ASSERT_VOP_LOCKED(" star "a->a_"arg", \""uname"\");");
80a9643ea8Slogwang		else if (lockdata[name, arg, pos] == "U")
81a9643ea8Slogwang			printc(ind"ASSERT_VOP_UNLOCKED(" star "a->a_"arg", \""uname"\");");
82a9643ea8Slogwang		else if (lockdata[name, arg, pos] == "E")
83a9643ea8Slogwang			printc(ind"ASSERT_VOP_ELOCKED(" star "a->a_"arg", \""uname"\");");
84a9643ea8Slogwang		else if (0) {
85a9643ea8Slogwang			# XXX More checks!
86a9643ea8Slogwang		}
87a9643ea8Slogwang	}
88a9643ea8Slogwang}
89a9643ea8Slogwang
90*22ce4affSfengbojiangfunction add_debugpre(name)
91*22ce4affSfengbojiang{
92*22ce4affSfengbojiang	if (lockdata[name, "debugpre"]) {
93*22ce4affSfengbojiang		printc("#ifdef DEBUG_VFS_LOCKS");
94*22ce4affSfengbojiang		printc("\t"lockdata[name, "debugpre"]"(a);");
95*22ce4affSfengbojiang		printc("#endif");
96*22ce4affSfengbojiang	}
97*22ce4affSfengbojiang}
98*22ce4affSfengbojiang
99*22ce4affSfengbojiangfunction add_debugpost(name)
100*22ce4affSfengbojiang{
101*22ce4affSfengbojiang	if (lockdata[name, "debugpost"]) {
102*22ce4affSfengbojiang		printc("#ifdef DEBUG_VFS_LOCKS");
103*22ce4affSfengbojiang		printc("\t"lockdata[name, "debugpost"]"(a, rc);");
104*22ce4affSfengbojiang		printc("#endif");
105*22ce4affSfengbojiang	}
106*22ce4affSfengbojiang}
107*22ce4affSfengbojiang
108a9643ea8Slogwangfunction add_pre(name)
109a9643ea8Slogwang{
110a9643ea8Slogwang	if (lockdata[name, "pre"]) {
111a9643ea8Slogwang		printc("\t"lockdata[name, "pre"]"(a);");
112a9643ea8Slogwang	}
113a9643ea8Slogwang}
114a9643ea8Slogwang
115a9643ea8Slogwangfunction add_post(name)
116a9643ea8Slogwang{
117a9643ea8Slogwang	if (lockdata[name, "post"]) {
118a9643ea8Slogwang		printc("\t"lockdata[name, "post"]"(a, rc);");
119a9643ea8Slogwang	}
120a9643ea8Slogwang}
121a9643ea8Slogwang
122*22ce4affSfengbojiangfunction can_inline(name)
123*22ce4affSfengbojiang{
124*22ce4affSfengbojiang	if (lockdata[name, "pre"])
125*22ce4affSfengbojiang		return 0;
126*22ce4affSfengbojiang	if (lockdata[name, "post"])
127*22ce4affSfengbojiang		return 0;
128*22ce4affSfengbojiang	return 1;
129*22ce4affSfengbojiang}
130*22ce4affSfengbojiang
131a9643ea8Slogwangfunction find_arg_with_type (type)
132a9643ea8Slogwang{
133a9643ea8Slogwang	for (jj = 0; jj < numargs; jj++) {
134a9643ea8Slogwang		if (types[jj] == type) {
135a9643ea8Slogwang			return "VOPARG_OFFSETOF(struct " \
136a9643ea8Slogwang			    name "_args,a_" args[jj] ")";
137a9643ea8Slogwang		}
138a9643ea8Slogwang	}
139a9643ea8Slogwang
140a9643ea8Slogwang	return "VDESC_NO_OFFSET";
141a9643ea8Slogwang}
142a9643ea8Slogwang
143a9643ea8SlogwangBEGIN{
144a9643ea8Slogwang
145a9643ea8Slogwang# Process the command line
146a9643ea8Slogwangfor (i = 1; i < ARGC; i++) {
147a9643ea8Slogwang	arg = ARGV[i];
148a9643ea8Slogwang	if (arg !~ /^-[chpq]+$/ && arg !~ /\.src$/)
149a9643ea8Slogwang		usage();
150a9643ea8Slogwang	if (arg ~ /^-.*c/)
151a9643ea8Slogwang		cfile = "vnode_if.c";
152a9643ea8Slogwang	if (arg ~ /^-.*h/)
153a9643ea8Slogwang		hfile = "vnode_if.h";
154a9643ea8Slogwang	if (arg ~ /^-.*p/)
155a9643ea8Slogwang		pfile = "vnode_if_newproto.h";
156a9643ea8Slogwang	if (arg ~ /^-.*q/)
157a9643ea8Slogwang		qfile = "vnode_if_typedef.h";
158a9643ea8Slogwang	if (arg ~ /\.src$/)
159a9643ea8Slogwang		srcfile = arg;
160a9643ea8Slogwang}
161a9643ea8SlogwangARGC = 1;
162a9643ea8Slogwang
163a9643ea8Slogwangif (!cfile && !hfile && !pfile && !qfile)
164a9643ea8Slogwang	exit 0;
165a9643ea8Slogwang
166a9643ea8Slogwangif (!srcfile)
167a9643ea8Slogwang	usage();
168a9643ea8Slogwang
169*22ce4affSfengbojiang# Avoid a literal generated file tag here.
170*22ce4affSfengbojianggenerated = "@" "generated";
171*22ce4affSfengbojiang
172a9643ea8Slogwangcommon_head = \
173a9643ea8Slogwang    "/*\n" \
174*22ce4affSfengbojiang    " * This file is " generated " automatically.\n" \
175a9643ea8Slogwang    " * Do not modify anything in here by hand.\n" \
176a9643ea8Slogwang    " *\n" \
177a9643ea8Slogwang    " * Created from $FreeBSD$\n" \
178a9643ea8Slogwang    " */\n" \
179a9643ea8Slogwang    "\n";
180a9643ea8Slogwang
181a9643ea8Slogwangif (pfile) {
182a9643ea8Slogwang	printp(common_head)
183a9643ea8Slogwang	printp("struct vop_vector {")
184a9643ea8Slogwang	printp("\tstruct vop_vector\t*vop_default;")
185a9643ea8Slogwang	printp("\tvop_bypass_t\t*vop_bypass;")
186a9643ea8Slogwang}
187a9643ea8Slogwang
188a9643ea8Slogwangif (qfile) {
189a9643ea8Slogwang	printq(common_head)
190a9643ea8Slogwang}
191a9643ea8Slogwang
192a9643ea8Slogwangif (hfile) {
193a9643ea8Slogwang	printh(common_head "extern struct vnodeop_desc vop_default_desc;");
194a9643ea8Slogwang	printh("#include \"vnode_if_typedef.h\"")
195a9643ea8Slogwang	printh("#include \"vnode_if_newproto.h\"")
196a9643ea8Slogwang}
197a9643ea8Slogwang
198a9643ea8Slogwangif (cfile) {
199a9643ea8Slogwang	printc(common_head \
200a9643ea8Slogwang	    "#include <sys/param.h>\n" \
201a9643ea8Slogwang	    "#include <sys/event.h>\n" \
202a9643ea8Slogwang	    "#include <sys/kernel.h>\n" \
203a9643ea8Slogwang	    "#include <sys/mount.h>\n" \
204a9643ea8Slogwang	    "#include <sys/sdt.h>\n" \
205a9643ea8Slogwang	    "#include <sys/signalvar.h>\n" \
206a9643ea8Slogwang	    "#include <sys/systm.h>\n" \
207a9643ea8Slogwang	    "#include <sys/vnode.h>\n" \
208a9643ea8Slogwang	    "\n" \
209a9643ea8Slogwang	    "SDT_PROVIDER_DECLARE(vfs);\n" \
210a9643ea8Slogwang	    "\n" \
211a9643ea8Slogwang	    "struct vnodeop_desc vop_default_desc = {\n" \
212a9643ea8Slogwang	    "	\"default\",\n" \
213a9643ea8Slogwang	    "	0,\n" \
214*22ce4affSfengbojiang	    "   0,\n" \
215a9643ea8Slogwang	    "	(vop_bypass_t *)vop_panic,\n" \
216a9643ea8Slogwang	    "	NULL,\n" \
217a9643ea8Slogwang	    "	VDESC_NO_OFFSET,\n" \
218a9643ea8Slogwang	    "	VDESC_NO_OFFSET,\n" \
219a9643ea8Slogwang	    "	VDESC_NO_OFFSET,\n" \
220a9643ea8Slogwang	    "	VDESC_NO_OFFSET,\n" \
221a9643ea8Slogwang	    "};\n");
222a9643ea8Slogwang}
223a9643ea8Slogwang
224a9643ea8Slogwangwhile ((getline < srcfile) > 0) {
225a9643ea8Slogwang	fnr++;
226a9643ea8Slogwang	if (NF == 0)
227a9643ea8Slogwang		continue;
228a9643ea8Slogwang	if ($1 ~ /^%%/) {
229a9643ea8Slogwang		if (NF != 6 ||
230a9643ea8Slogwang		    $2 !~ /^[a-z_]+$/  ||  $3 !~ /^[a-z]+$/  ||
231a9643ea8Slogwang		    $4 !~ /^.$/  ||  $5 !~ /^.$/  ||  $6 !~ /^.$/) {
232a9643ea8Slogwang			die("Invalid %s construction", "%%");
233a9643ea8Slogwang			continue;
234a9643ea8Slogwang		}
235a9643ea8Slogwang		lockdata["vop_" $2, $3, "Entry"] = $4;
236a9643ea8Slogwang		lockdata["vop_" $2, $3, "OK"]    = $5;
237a9643ea8Slogwang		lockdata["vop_" $2, $3, "Error"] = $6;
238a9643ea8Slogwang		continue;
239a9643ea8Slogwang	}
240a9643ea8Slogwang
241a9643ea8Slogwang	if ($1 ~ /^%!/) {
242a9643ea8Slogwang		if (NF != 4 ||
243*22ce4affSfengbojiang		    ($3 != "pre" && $3 != "post" &&
244*22ce4affSfengbojiang		     $3 != "debugpre" && $3 != "debugpost")) {
245a9643ea8Slogwang			die("Invalid %s construction", "%!");
246a9643ea8Slogwang			continue;
247a9643ea8Slogwang		}
248a9643ea8Slogwang		lockdata["vop_" $2, $3] = $4;
249a9643ea8Slogwang		continue;
250a9643ea8Slogwang	}
251a9643ea8Slogwang	if ($1 ~ /^#/)
252a9643ea8Slogwang		continue;
253a9643ea8Slogwang
254a9643ea8Slogwang	# Get the function name.
255a9643ea8Slogwang	name = $1;
256a9643ea8Slogwang	uname = toupper(name);
257a9643ea8Slogwang
258a9643ea8Slogwang	# Get the function arguments.
259a9643ea8Slogwang	for (numargs = 0; ; ++numargs) {
260a9643ea8Slogwang		if ((getline < srcfile) <= 0) {
261a9643ea8Slogwang			die("Unable to read through the arguments for \"%s\"",
262a9643ea8Slogwang			    name);
263a9643ea8Slogwang		}
264a9643ea8Slogwang		fnr++;
265a9643ea8Slogwang		if ($1 ~ /^\};/)
266a9643ea8Slogwang			break;
267a9643ea8Slogwang
268a9643ea8Slogwang		# Delete comments, if any.
269a9643ea8Slogwang		gsub (/\/\*.*\*\//, "");
270a9643ea8Slogwang
271a9643ea8Slogwang		# Condense whitespace and delete leading/trailing space.
272a9643ea8Slogwang		gsub(/[[:space:]]+/, " ");
273a9643ea8Slogwang		sub(/^ /, "");
274a9643ea8Slogwang		sub(/ $/, "");
275a9643ea8Slogwang
276a9643ea8Slogwang		# Pick off direction.
277a9643ea8Slogwang		if ($1 != "INOUT" && $1 != "IN" && $1 != "OUT")
278a9643ea8Slogwang			die("No IN/OUT direction for \"%s\".", $0);
279a9643ea8Slogwang		dirs[numargs] = $1;
280a9643ea8Slogwang		sub(/^[A-Z]* /, "");
281a9643ea8Slogwang
282a9643ea8Slogwang		if ((reles[numargs] = $1) == "WILLRELE")
283a9643ea8Slogwang			sub(/^[A-Z]* /, "");
284a9643ea8Slogwang		else
285a9643ea8Slogwang			reles[numargs] = "WONTRELE";
286a9643ea8Slogwang
287a9643ea8Slogwang		# kill trailing ;
288a9643ea8Slogwang		if (sub(/;$/, "") < 1)
289a9643ea8Slogwang			die("Missing end-of-line ; in \"%s\".", $0);
290a9643ea8Slogwang
291a9643ea8Slogwang		# pick off variable name
292a9643ea8Slogwang		if ((argp = match($0, /[A-Za-z0-9_]+$/)) < 1)
293a9643ea8Slogwang			die("Missing var name \"a_foo\" in \"%s\".", $0);
294a9643ea8Slogwang		args[numargs] = substr($0, argp);
295a9643ea8Slogwang		$0 = substr($0, 1, argp - 1);
296a9643ea8Slogwang
297a9643ea8Slogwang		# what is left must be type
298a9643ea8Slogwang		# remove trailing space (if any)
299a9643ea8Slogwang		sub(/ $/, "");
300a9643ea8Slogwang		types[numargs] = $0;
301a9643ea8Slogwang	}
302a9643ea8Slogwang	if (numargs > 4)
303a9643ea8Slogwang		ctrargs = 4;
304a9643ea8Slogwang	else
305a9643ea8Slogwang		ctrargs = numargs;
306a9643ea8Slogwang	ctrstr = ctrargs "(KTR_VOP, \"VOP\", \"" uname "\", (uintptr_t)a,\n\t    ";
307a9643ea8Slogwang	ctrstr = ctrstr "\"" args[0] ":0x%jX\", (uintptr_t)a->a_" args[0];
308a9643ea8Slogwang	for (i = 1; i < ctrargs; ++i)
309a9643ea8Slogwang		ctrstr = ctrstr ", \"" args[i] ":0x%jX\", a->a_" args[i];
310a9643ea8Slogwang	ctrstr = ctrstr ");";
311a9643ea8Slogwang
312a9643ea8Slogwang	if (pfile) {
313a9643ea8Slogwang		printp("\t"name"_t\t*"name";")
314a9643ea8Slogwang	}
315a9643ea8Slogwang	if (qfile) {
316a9643ea8Slogwang		printq("struct "name"_args;")
317a9643ea8Slogwang		printq("typedef int "name"_t(struct "name"_args *);\n")
318a9643ea8Slogwang	}
319a9643ea8Slogwang
320a9643ea8Slogwang	if (hfile) {
321a9643ea8Slogwang		# Print out the vop_F_args structure.
322a9643ea8Slogwang		printh("struct "name"_args {\n\tstruct vop_generic_args a_gen;");
323a9643ea8Slogwang		for (i = 0; i < numargs; ++i)
324a9643ea8Slogwang			printh("\t" t_spc(types[i]) "a_" args[i] ";");
325a9643ea8Slogwang		printh("};");
326a9643ea8Slogwang		printh("");
327a9643ea8Slogwang
328a9643ea8Slogwang		# Print out extern declaration.
329a9643ea8Slogwang		printh("extern struct vnodeop_desc " name "_desc;");
330a9643ea8Slogwang		printh("");
331a9643ea8Slogwang
332a9643ea8Slogwang		# Print out function prototypes.
333a9643ea8Slogwang		printh("int " uname "_AP(struct " name "_args *);");
334a9643ea8Slogwang		printh("int " uname "_APV(struct vop_vector *vop, struct " name "_args *);");
335a9643ea8Slogwang		printh("");
336a9643ea8Slogwang		printh("static __inline int " uname "(");
337a9643ea8Slogwang		for (i = 0; i < numargs; ++i) {
338a9643ea8Slogwang			printh("\t" t_spc(types[i]) args[i] \
339a9643ea8Slogwang			    (i < numargs - 1 ? "," : ")"));
340a9643ea8Slogwang		}
341a9643ea8Slogwang		printh("{");
342a9643ea8Slogwang		printh("\tstruct " name "_args a;");
343a9643ea8Slogwang		printh("");
344a9643ea8Slogwang		printh("\ta.a_gen.a_desc = &" name "_desc;");
345a9643ea8Slogwang		for (i = 0; i < numargs; ++i)
346a9643ea8Slogwang			printh("\ta.a_" args[i] " = " args[i] ";");
347*22ce4affSfengbojiang		if (can_inline(name)) {
348*22ce4affSfengbojiang			printh("\n#if !defined(DEBUG_VFS_LOCKS) && !defined(INVARIANTS) && !defined(KTR)");
349*22ce4affSfengbojiang			printh("\tif (!SDT_PROBES_ENABLED())");
350*22ce4affSfengbojiang			printh("\t\treturn (" args[0]"->v_op->"name"(&a));");
351*22ce4affSfengbojiang			printh("\telse");
352*22ce4affSfengbojiang			printh("\t\treturn (" uname "_APV("args[0]"->v_op, &a));");
353*22ce4affSfengbojiang			printh("#else");
354*22ce4affSfengbojiang		}
355a9643ea8Slogwang		printh("\treturn (" uname "_APV("args[0]"->v_op, &a));");
356*22ce4affSfengbojiang		if (can_inline(name))
357*22ce4affSfengbojiang			printh("#endif");
358*22ce4affSfengbojiang
359a9643ea8Slogwang		printh("}");
360a9643ea8Slogwang
361a9643ea8Slogwang		printh("");
362a9643ea8Slogwang	}
363a9643ea8Slogwang
364a9643ea8Slogwang	if (cfile) {
365*22ce4affSfengbojiang		funcarr[name] = 1;
366a9643ea8Slogwang		# Print out the vop_F_vp_offsets structure.  This all depends
367a9643ea8Slogwang		# on naming conventions and nothing else.
368a9643ea8Slogwang		printc("static int " name "_vp_offsets[] = {");
369a9643ea8Slogwang		# as a side effect, figure out the releflags
370a9643ea8Slogwang		releflags = "";
371a9643ea8Slogwang		vpnum = 0;
372a9643ea8Slogwang		for (i = 0; i < numargs; i++) {
373a9643ea8Slogwang			if (types[i] == "struct vnode *") {
374a9643ea8Slogwang				printc("\tVOPARG_OFFSETOF(struct " name \
375a9643ea8Slogwang				    "_args,a_" args[i] "),");
376a9643ea8Slogwang				if (reles[i] == "WILLRELE") {
377a9643ea8Slogwang					releflags = releflags \
378a9643ea8Slogwang					    "|VDESC_VP" vpnum "_WILLRELE";
379a9643ea8Slogwang				}
380a9643ea8Slogwang				vpnum++;
381a9643ea8Slogwang			}
382a9643ea8Slogwang		}
383a9643ea8Slogwang
384a9643ea8Slogwang		sub(/^\|/, "", releflags);
385a9643ea8Slogwang		printc("\tVDESC_NO_OFFSET");
386a9643ea8Slogwang		printc("};");
387a9643ea8Slogwang
388a9643ea8Slogwang		printc("\n");
389a9643ea8Slogwang		printc("SDT_PROBE_DEFINE2(vfs, vop, " name ", entry, \"struct vnode *\", \"struct " name "_args *\");\n");
390a9643ea8Slogwang		printc("SDT_PROBE_DEFINE3(vfs, vop, " name ", return, \"struct vnode *\", \"struct " name "_args *\", \"int\");\n");
391a9643ea8Slogwang
392a9643ea8Slogwang		# Print out function.
393a9643ea8Slogwang		printc("\nint\n" uname "_AP(struct " name "_args *a)");
394a9643ea8Slogwang		printc("{");
395a9643ea8Slogwang		printc("");
396a9643ea8Slogwang		printc("\treturn(" uname "_APV(a->a_" args[0] "->v_op, a));");
397a9643ea8Slogwang		printc("}");
398a9643ea8Slogwang		printc("\nint\n" uname "_APV(struct vop_vector *vop, struct " name "_args *a)");
399a9643ea8Slogwang		printc("{");
400a9643ea8Slogwang		printc("\tint rc;");
401a9643ea8Slogwang		printc("");
402a9643ea8Slogwang		printc("\tVNASSERT(a->a_gen.a_desc == &" name "_desc, a->a_" args[0]",");
403a9643ea8Slogwang		printc("\t    (\"Wrong a_desc in " name "(%p, %p)\", a->a_" args[0]", a));");
404a9643ea8Slogwang		printc("\tVNASSERT(vop != NULL, a->a_" args[0]", (\"No "name"(%p, %p)\", a->a_" args[0]", a));")
405*22ce4affSfengbojiang		printc("\tKTR_START" ctrstr);
406*22ce4affSfengbojiang		add_debugpre(name);
407*22ce4affSfengbojiang		add_pre(name);
408a9643ea8Slogwang		for (i = 0; i < numargs; ++i)
409a9643ea8Slogwang			add_debug_code(name, args[i], "Entry", "\t");
410*22ce4affSfengbojiang		printc("\tif (!SDT_PROBES_ENABLED()) {");
411a9643ea8Slogwang		printc("\t\trc = vop->"name"(a);")
412*22ce4affSfengbojiang		printc("\t} else {")
413*22ce4affSfengbojiang		printc("\t\tSDT_PROBE2(vfs, vop, " name ", entry, a->a_" args[0] ", a);");
414*22ce4affSfengbojiang		printc("\t\trc = vop->"name"(a);")
415*22ce4affSfengbojiang		printc("\t\tSDT_PROBE3(vfs, vop, " name ", return, a->a_" args[0] ", a, rc);");
416*22ce4affSfengbojiang		printc("\t}")
417a9643ea8Slogwang		printc("\tif (rc == 0) {");
418a9643ea8Slogwang		for (i = 0; i < numargs; ++i)
419a9643ea8Slogwang			add_debug_code(name, args[i], "OK", "\t\t");
420a9643ea8Slogwang		printc("\t} else {");
421a9643ea8Slogwang		for (i = 0; i < numargs; ++i)
422a9643ea8Slogwang			add_debug_code(name, args[i], "Error", "\t\t");
423a9643ea8Slogwang		printc("\t}");
424a9643ea8Slogwang		add_post(name);
425*22ce4affSfengbojiang		add_debugpost(name);
426a9643ea8Slogwang		printc("\tKTR_STOP" ctrstr);
427a9643ea8Slogwang		printc("\treturn (rc);");
428a9643ea8Slogwang		printc("}\n");
429a9643ea8Slogwang
430a9643ea8Slogwang		# Print out the vnodeop_desc structure.
431a9643ea8Slogwang		printc("struct vnodeop_desc " name "_desc = {");
432a9643ea8Slogwang		# printable name
433a9643ea8Slogwang		printc("\t\"" name "\",");
434a9643ea8Slogwang		# flags
435a9643ea8Slogwang		vppwillrele = "";
436a9643ea8Slogwang		for (i = 0; i < numargs; i++) {
437a9643ea8Slogwang			if (types[i] == "struct vnode **" && \
438a9643ea8Slogwang			    reles[i] == "WILLRELE") {
439a9643ea8Slogwang				vppwillrele = "|VDESC_VPP_WILLRELE";
440a9643ea8Slogwang			}
441a9643ea8Slogwang		}
442a9643ea8Slogwang
443a9643ea8Slogwang		if (!releflags)
444a9643ea8Slogwang			releflags = "0";
445a9643ea8Slogwang		printc("\t" releflags vppwillrele ",");
446a9643ea8Slogwang
447*22ce4affSfengbojiang		# index in struct vop_vector
448*22ce4affSfengbojiang		printc("\t__offsetof(struct vop_vector, " name "),");
449a9643ea8Slogwang		# function to call
450a9643ea8Slogwang		printc("\t(vop_bypass_t *)" uname "_AP,");
451a9643ea8Slogwang		# vp offsets
452a9643ea8Slogwang		printc("\t" name "_vp_offsets,");
453a9643ea8Slogwang		# vpp (if any)
454a9643ea8Slogwang		printc("\t" find_arg_with_type("struct vnode **") ",");
455a9643ea8Slogwang		# cred (if any)
456a9643ea8Slogwang		printc("\t" find_arg_with_type("struct ucred *") ",");
457a9643ea8Slogwang		# thread (if any)
458a9643ea8Slogwang		printc("\t" find_arg_with_type("struct thread *") ",");
459a9643ea8Slogwang		# componentname
460a9643ea8Slogwang		printc("\t" find_arg_with_type("struct componentname *") ",");
461a9643ea8Slogwang		# transport layer information
462a9643ea8Slogwang		printc("};\n");
463a9643ea8Slogwang	}
464a9643ea8Slogwang}
465a9643ea8Slogwang
466*22ce4affSfengbojiangif (cfile) {
467*22ce4affSfengbojiang	printc("void");
468*22ce4affSfengbojiang	printc("vfs_vector_op_register(struct vop_vector *orig_vop)");
469*22ce4affSfengbojiang	printc("{");
470*22ce4affSfengbojiang	printc("\tstruct vop_vector *vop;");
471*22ce4affSfengbojiang	printc("");
472*22ce4affSfengbojiang	printc("\tif (orig_vop->registered)");
473*22ce4affSfengbojiang	printc("\t\tpanic(\"%s: vop_vector %p already registered\",")
474*22ce4affSfengbojiang	printc("\t\t    __func__, orig_vop);");
475*22ce4affSfengbojiang	printc("");
476*22ce4affSfengbojiang	for (name in funcarr) {
477*22ce4affSfengbojiang		printc("\tvop = orig_vop;");
478*22ce4affSfengbojiang		printc("\twhile (vop != NULL && \\");
479*22ce4affSfengbojiang		printc("\t    vop->"name" == NULL && vop->vop_bypass == NULL)")
480*22ce4affSfengbojiang		printc("\t\tvop = vop->vop_default;")
481*22ce4affSfengbojiang		printc("\tif (vop != NULL)");
482*22ce4affSfengbojiang		printc("\t\torig_vop->"name" = vop->"name";");
483*22ce4affSfengbojiang		printc("");
484*22ce4affSfengbojiang	}
485*22ce4affSfengbojiang	printc("\tvop = orig_vop;");
486*22ce4affSfengbojiang	printc("\twhile (vop != NULL && vop->vop_bypass == NULL)")
487*22ce4affSfengbojiang	printc("\t\tvop = vop->vop_default;")
488*22ce4affSfengbojiang	printc("\tif (vop != NULL)");
489*22ce4affSfengbojiang	printc("\t\torig_vop->vop_bypass = vop->vop_bypass;");
490*22ce4affSfengbojiang	printc("");
491*22ce4affSfengbojiang	for (name in funcarr) {
492*22ce4affSfengbojiang		printc("\tif (orig_vop->"name" == NULL)");
493*22ce4affSfengbojiang		printc("\t\torig_vop->"name" = (void *)orig_vop->vop_bypass;");
494*22ce4affSfengbojiang	}
495*22ce4affSfengbojiang	printc("");
496*22ce4affSfengbojiang	printc("\torig_vop->registered = true;");
497*22ce4affSfengbojiang	printc("}")
498*22ce4affSfengbojiang}
499*22ce4affSfengbojiang
500*22ce4affSfengbojiangif (hfile) {
501*22ce4affSfengbojiang	printh("void vfs_vector_op_register(struct vop_vector *orig_vop);");
502*22ce4affSfengbojiang}
503*22ce4affSfengbojiang
504*22ce4affSfengbojiangif (pfile) {
505*22ce4affSfengbojiang	printp("\tbool\tregistered;")
506a9643ea8Slogwang	printp("};")
507*22ce4affSfengbojiang}
508a9643ea8Slogwang
509a9643ea8Slogwangif (hfile)
510a9643ea8Slogwang	close(hfile);
511a9643ea8Slogwangif (cfile)
512a9643ea8Slogwang	close(cfile);
513a9643ea8Slogwangif (pfile)
514a9643ea8Slogwang	close(pfile);
515a9643ea8Slogwangclose(srcfile);
516a9643ea8Slogwang
517a9643ea8Slogwangexit 0;
518a9643ea8Slogwang
519a9643ea8Slogwang}
520