Home | History | Annotate | Line # | Download | only in kern
vnode_if.sh revision 1.1
      1 #!/bin/sh -
      2 #
      3 # Copyright (c) 1992, 1993
      4 #	The Regents of the University of California.  All rights reserved.
      5 #
      6 # Redistribution and use in source and binary forms, with or without
      7 # modification, are permitted provided that the following conditions
      8 # are met:
      9 # 1. Redistributions of source code must retain the above copyright
     10 #    notice, this list of conditions and the following disclaimer.
     11 # 2. Redistributions in binary form must reproduce the above copyright
     12 #    notice, this list of conditions and the following disclaimer in the
     13 #    documentation and/or other materials provided with the distribution.
     14 # 3. All advertising materials mentioning features or use of this software
     15 #    must display the following acknowledgement:
     16 #	This product includes software developed by the University of
     17 #	California, Berkeley and its contributors.
     18 # 4. Neither the name of the University nor the names of its contributors
     19 #    may be used to endorse or promote products derived from this software
     20 #    without specific prior written permission.
     21 #
     22 # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25 # ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32 # SUCH DAMAGE.
     33 #
     34 #	from: @(#)vnode_if.sh	8.1 (Berkeley) 6/10/93
     35 #	$Id: vnode_if.sh,v 1.1 1994/06/08 11:29:01 mycroft Exp $
     36 #
     37 
     38 # Script to produce VFS front-end sugar.
     39 #
     40 # usage: vnode_if.sh srcfile
     41 #	(where srcfile is currently /sys/kern/vnode_if.src)
     42 #
     43 # These awk scripts are not particularly well written, specifically they
     44 # don't use arrays well and figure out the same information repeatedly.
     45 # Please rewrite them if you actually understand how to use awk.  Note,
     46 # they use nawk extensions and gawk's toupper.
     47 
     48 if [ $# -ne 1 ] ; then
     49 	echo 'usage: vnode_if.sh srcfile'
     50 	exit 1
     51 fi
     52 
     53 # Name of the source file.
     54 SRC=$1
     55 
     56 # Names of the created files.
     57 CFILE=vnode_if.c
     58 HEADER=vnode_if.h
     59 
     60 # Awk program (must support nawk extensions and gawk's "toupper")
     61 # Use "awk" at Berkeley, "gawk" elsewhere.
     62 AWK=awk
     63 
     64 # Print out header information for vnode_if.h.
     65 cat << END_OF_LEADING_COMMENT > $HEADER
     66 /*
     67  * This file is produced automatically.
     68  * Do not modify anything in here by hand.
     69  *
     70  * Created from @(#)vnode_if.sh	8.1 (Berkeley) 6/10/93
     71  */
     72 
     73 extern struct vnodeop_desc vop_default_desc;
     74 END_OF_LEADING_COMMENT
     75 
     76 # Awk script to take vnode_if.src and turn it into vnode_if.h.
     77 $AWK '
     78 	NF == 0 || $0 ~ "^#" {
     79 		next;
     80 	}
     81 	{
     82 		# Get the function name.
     83 		name = $1;
     84 		uname = toupper(name);
     85 
     86 		# Get the function arguments.
     87 		for (c1 = 0;; ++c1) {
     88 			if (getline <= 0)
     89 				exit
     90 			if ($0 ~ "^};")
     91 				break;
     92 			a[c1] = $0;
     93 		}
     94 
     95 		# Print out the vop_F_args structure.
     96 		printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n",
     97 		    name);
     98 		for (c2 = 0; c2 < c1; ++c2) {
     99 			c3 = split(a[c2], t);
    100 			printf("\t");
    101 			if (t[2] ~ "WILLRELE")
    102 				c4 = 3;
    103 			else 
    104 				c4 = 2;
    105 			for (; c4 < c3; ++c4)
    106 				printf("%s ", t[c4]);
    107 			beg = match(t[c3], "[^*]");
    108 			printf("%sa_%s\n",
    109 			    substr(t[c4], 0, beg - 1), substr(t[c4], beg));
    110 		}
    111 		printf("};\n");
    112 
    113 		# Print out extern declaration.
    114 		printf("extern struct vnodeop_desc %s_desc;\n", name);
    115 
    116 		# Print out inline struct.
    117 		printf("static inline int %s(", uname);
    118 		sep = ", ";
    119 		for (c2 = 0; c2 < c1; ++c2) {
    120 			if (c2 == c1 - 1)
    121 				sep = ")\n";
    122 			c3 = split(a[c2], t);
    123 			beg = match(t[c3], "[^*]");
    124 			end = match(t[c3], ";");
    125 			printf("%s%s", substr(t[c3], beg, end - beg), sep);
    126 		}
    127 		for (c2 = 0; c2 < c1; ++c2) {
    128 			c3 = split(a[c2], t);
    129 			printf("\t");
    130 			if (t[2] ~ "WILLRELE")
    131 				c4 = 3;
    132 			else
    133 				c4 = 2;
    134 			for (; c4 < c3; ++c4)
    135 				printf("%s ", t[c4]);
    136 			beg = match(t[c3], "[^*]");
    137 			printf("%s%s\n",
    138 			    substr(t[c4], 0, beg - 1), substr(t[c4], beg));
    139 		}
    140 		printf("{\n\tstruct %s_args a;\n\n", name);
    141 		printf("\ta.a_desc = VDESC(%s);\n", name);
    142 		for (c2 = 0; c2 < c1; ++c2) {
    143 			c3 = split(a[c2], t);
    144 			printf("\t");
    145 			beg = match(t[c3], "[^*]");
    146 			end = match(t[c3], ";");
    147 			printf("a.a_%s = %s\n",
    148 			    substr(t[c3], beg, end - beg), substr(t[c3], beg));
    149 		}
    150 		c1 = split(a[0], t);
    151 		beg = match(t[c1], "[^*]");
    152 		end = match(t[c1], ";");
    153 		printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n",
    154 		    substr(t[c1], beg, end - beg), name);
    155 	}' < $SRC >> $HEADER
    156 
    157 # Print out header information for vnode_if.c.
    158 cat << END_OF_LEADING_COMMENT > $CFILE
    159 /*
    160  * This file is produced automatically.
    161  * Do not modify anything in here by hand.
    162  *
    163  * Created from @(#)vnode_if.sh	8.1 (Berkeley) 6/10/93
    164  */
    165 
    166 #include <sys/param.h>
    167 #include <sys/mount.h>
    168 #include <sys/vnode.h>
    169 
    170 struct vnodeop_desc vop_default_desc = {
    171 	0,
    172 	"default",
    173 	0,
    174 	NULL,
    175 	VDESC_NO_OFFSET,
    176 	VDESC_NO_OFFSET,
    177 	VDESC_NO_OFFSET,
    178 	VDESC_NO_OFFSET,
    179 	NULL,
    180 };
    181 
    182 END_OF_LEADING_COMMENT
    183 
    184 # Awk script to take vnode_if.src and turn it into vnode_if.c.
    185 $AWK 'function kill_surrounding_ws (s) {
    186 		sub (/^[ \t]*/, "", s);
    187 		sub (/[ \t]*$/, "", s);
    188 		return s;
    189 	}
    190 
    191 	function read_args() {
    192 		numargs = 0;
    193 		while (getline ln) {
    194 			if (ln ~ /}/) {
    195 				break;
    196 			};
    197 	
    198 			# Delete comments, if any.
    199 			gsub (/\/\*.*\*\//, "", ln);
    200 			
    201 			# Delete leading/trailing space.
    202 			ln = kill_surrounding_ws(ln);
    203 	
    204 			# Pick off direction.
    205 			if (1 == sub(/^INOUT[ \t]+/, "", ln))
    206 				dir = "INOUT";
    207 			else if (1 == sub(/^IN[ \t]+/, "", ln))
    208 				dir = "IN";
    209 			else if (1 == sub(/^OUT[ \t]+/, "", ln))
    210 				dir = "OUT";
    211 			else
    212 				bail("No IN/OUT direction for \"" ln "\".");
    213 
    214 			# check for "WILLRELE"
    215 			if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) {
    216 				rele = "WILLRELE";
    217 			} else {
    218 				rele = "WONTRELE";
    219 			};
    220 	
    221 			# kill trailing ;
    222 			if (1 != sub (/;$/, "", ln)) {
    223 				bail("Missing end-of-line ; in \"" ln "\".");
    224 			};
    225 	
    226 			# pick off variable name
    227 			if (!(i = match(ln, /[A-Za-z0-9_]+$/))) {
    228 				bail("Missing var name \"a_foo\" in \"" ln "\".");
    229 			};
    230 			arg = substr (ln, i);
    231 			# Want to <<substr(ln, i) = "";>>, but nawk cannot.
    232 			# Hack around this.
    233 			ln = substr(ln, 1, i-1);
    234 	
    235 			# what is left must be type
    236 			# (put clean it up some)
    237 			type = ln;
    238 			gsub (/[ \t]+/, " ", type);   # condense whitespace
    239 			type = kill_surrounding_ws(type);
    240 	
    241 			# (boy this was easier in Perl)
    242 	
    243 			numargs++;
    244 			dirs[numargs] = dir;
    245 			reles[numargs] = rele;
    246 			types[numargs] = type;
    247 			args[numargs] = arg;
    248 		};
    249 	}
    250 
    251 	function generate_operation_vp_offsets() {
    252 		printf ("int %s_vp_offsets[] = {\n", name);
    253 		# as a side effect, figure out the releflags
    254 		releflags = "";
    255 		vpnum = 0;
    256 		for (i=1; i<=numargs; i++) {
    257 			if (types[i] == "struct vnode *") {
    258 				printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
    259 					name, args[i]);
    260 				if (reles[i] == "WILLRELE") {
    261 					releflags = releflags "|VDESC_VP" vpnum "_WILLRELE";
    262 				};
    263 				vpnum++;
    264 			};
    265 		};
    266 		sub (/^\|/, "", releflags);
    267 		print "\tVDESC_NO_OFFSET";
    268 		print "};";
    269 	}
    270 	
    271 	function find_arg_with_type (type) {
    272 		for (i=1; i<=numargs; i++) {
    273 			if (types[i] == type) {
    274 				return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")";
    275 			};
    276 		};
    277 		return "VDESC_NO_OFFSET";
    278 	}
    279 	
    280 	function generate_operation_desc() {
    281 		printf ("struct vnodeop_desc %s_desc = {\n", name);
    282 		# offset
    283 		printf ("\t0,\n");
    284 		# printable name
    285 		printf ("\t\"%s\",\n", name);
    286 		# flags
    287 		vppwillrele = "";
    288 		for (i=1; i<=numargs; i++) {
    289 			if (types[i] == "struct vnode **" &&
    290 				(reles[i] == "WILLRELE")) {
    291 				vppwillrele = "|VDESC_VPP_WILLRELE";
    292 			};
    293 		};
    294 		if (releflags == "") {
    295 			printf ("\t0%s,\n", vppwillrele);
    296 		} else {
    297 			printf ("\t%s%s,\n", releflags, vppwillrele);
    298 		};
    299 		# vp offsets
    300 		printf ("\t%s_vp_offsets,\n", name);
    301 		# vpp (if any)
    302 		printf ("\t%s,\n", find_arg_with_type("struct vnode **"));
    303 		# cred (if any)
    304 		printf ("\t%s,\n", find_arg_with_type("struct ucred *"));
    305 		# proc (if any)
    306 		printf ("\t%s,\n", find_arg_with_type("struct proc *"));
    307 		# componentname
    308 		printf ("\t%s,\n", find_arg_with_type("struct componentname *"));
    309 		# transport layer information
    310 		printf ("\tNULL,\n};\n");
    311 	}
    312 
    313 	NF == 0 || $0 ~ "^#" {
    314 		next;
    315 	}
    316 	{
    317 		# get the function name
    318 		name = $1;
    319 
    320 		# get the function arguments
    321 		read_args();
    322 
    323 		# Print out the vop_F_vp_offsets structure.  This all depends
    324 		# on naming conventions and nothing else.
    325 		generate_operation_vp_offsets();
    326 
    327 		# Print out the vnodeop_desc structure.
    328 		generate_operation_desc();
    329 
    330 		printf "\n";
    331 
    332 	}' < $SRC >> $CFILE
    333 # THINGS THAT DON'T WORK RIGHT YET.
    334 # 
    335 # Two existing BSD vnodeops (bwrite and strategy) don't take any vnodes as
    336 # arguments.  This means that these operations can't function successfully
    337 # through a bypass routine.
    338 #
    339 # Bwrite and strategy will be replaced when the VM page/buffer cache
    340 # integration happens.
    341 #
    342 # To get around this problem for now we handle these ops as special cases.
    343 
    344 cat << END_OF_SPECIAL_CASES >> $HEADER
    345 #include <sys/buf.h>
    346 struct vop_strategy_args {
    347 	struct vnodeop_desc *a_desc;
    348 	struct buf *a_bp;
    349 };
    350 extern struct vnodeop_desc vop_strategy_desc;
    351 static inline int VOP_STRATEGY(bp)
    352 	struct buf *bp;
    353 {
    354 	struct vop_strategy_args a;
    355 
    356 	a.a_desc = VDESC(vop_strategy);
    357 	a.a_bp = bp;
    358 	return (VCALL((bp)->b_vp, VOFFSET(vop_strategy), &a));
    359 }
    360 
    361 struct vop_bwrite_args {
    362 	struct vnodeop_desc *a_desc;
    363 	struct buf *a_bp;
    364 };
    365 extern struct vnodeop_desc vop_bwrite_desc;
    366 static inline int VOP_BWRITE(bp)
    367 	struct buf *bp;
    368 {
    369 	struct vop_bwrite_args a;
    370 
    371 	a.a_desc = VDESC(vop_bwrite);
    372 	a.a_bp = bp;
    373 	return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a));
    374 }
    375 END_OF_SPECIAL_CASES
    376 
    377 cat << END_OF_SPECIAL_CASES >> $CFILE
    378 int vop_strategy_vp_offsets[] = {
    379 	VDESC_NO_OFFSET
    380 };
    381 struct vnodeop_desc vop_strategy_desc = {
    382 	0,
    383 	"vop_strategy",
    384 	0,
    385 	vop_strategy_vp_offsets,
    386 	VDESC_NO_OFFSET,
    387 	VDESC_NO_OFFSET,
    388 	VDESC_NO_OFFSET,
    389 	VDESC_NO_OFFSET,
    390 	NULL,
    391 };
    392 int vop_bwrite_vp_offsets[] = {
    393 	VDESC_NO_OFFSET
    394 };
    395 struct vnodeop_desc vop_bwrite_desc = {
    396 	0,
    397 	"vop_bwrite",
    398 	0,
    399 	vop_bwrite_vp_offsets,
    400 	VDESC_NO_OFFSET,
    401 	VDESC_NO_OFFSET,
    402 	VDESC_NO_OFFSET,
    403 	VDESC_NO_OFFSET,
    404 	NULL,
    405 };
    406 END_OF_SPECIAL_CASES
    407 
    408 # Add the vfs_op_descs array to the C file.
    409 $AWK '
    410 	BEGIN {
    411 		printf("\nstruct vnodeop_desc *vfs_op_descs[] = {\n");
    412 		printf("\t&vop_default_desc,	/* MUST BE FIRST */\n");
    413 		printf("\t&vop_strategy_desc,	/* XXX: SPECIAL CASE */\n");
    414 		printf("\t&vop_bwrite_desc,	/* XXX: SPECIAL CASE */\n");
    415 	}
    416 	END {
    417 		printf("\tNULL\n};\n");
    418 	}
    419 	NF == 0 || $0 ~ "^#" {
    420 		next;
    421 	}
    422 	{
    423 		# Get the function name.
    424 		printf("\t&%s_desc,\n", $1);
    425 
    426 		# Skip the function arguments.
    427 		for (;;) {
    428 			if (getline <= 0)
    429 				exit
    430 			if ($0 ~ "^};")
    431 				break;
    432 		}
    433 	}' < $SRC >> $CFILE
    434 
    435