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