# Copyright (c) 1992 The Regents of the University of California.
# %sccs.include.redist.sh%
# @(#)vnode_if.sh 7.2 (Berkeley) %G%
# Script to produce VFS front-end sugar.
# usage: vnode_if.sh srcfile
# (where srcfile is currently /sys/kern/vnode_if.src)
# These awk scripts are not particularly well written, specifically they
# don't use arrays well and figure out the same information repeatedly.
# Please rewrite them if you actually understand how to use awk. Note,
# they use nawk extensions.
printf 'usage: vnode_if.sh srcfile\n'
# Name of the source file.
# Names of the created files.
# Print out header information for vnode_if.h.
cat << END_OF_LEADING_COMMENT > $HEADER
* This file is produced by the script /sys/kern/vnode_if.sh.
* Do not modify anything in here by hand.
* @(#)vnode_if.sh 7.2 (Berkeley) %G%
extern struct vnodeop_desc vop_default_desc;
# Awk script to take vnode_if.src and turn it into vnode_if.h.
# Get the function arguments.
# Print out the vop_F_args structure.
printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n",
for (c2 = 0; c2 < c1; ++c2) {
for (c4 = 2; c4 < c3; ++c4)
beg = match(t[c3], "[^*]");
substr(t[c4], 0, beg - 1), substr(t[c4], beg));
# Print out extern declaration.
printf("extern struct vnodeop_desc %s_desc;\n", name);
# Print out inline struct.
printf("static inline int %s(", uname);
for (c2 = 0; c2 < c1; ++c2) {
beg = match(t[c3], "[^*]");
printf("%s%s", substr(t[c3], beg, end - beg), sep);
for (c2 = 0; c2 < c1; ++c2) {
for (c4 = 2; c4 < c3; ++c4)
beg = match(t[c3], "[^*]");
substr(t[c4], 0, beg - 1), substr(t[c4], beg));
printf("{\n\tstruct %s_args a;\n\n", name);
printf("\ta.a_desc = VDESC(%s);\n", name);
for (c2 = 0; c2 < c1; ++c2) {
beg = match(t[c3], "[^*]");
substr(t[c3], beg, end - beg), substr(t[c3], beg));
beg = match(t[c1], "[^*]");
printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n",
substr(t[c1], beg, end - beg), name);
# Print out header information for vnode_if.c.
cat << END_OF_LEADING_COMMENT > $CFILE
* This file is produced by the script /sys/kern/vnode_if.sh.
* Do not modify anything in here by hand.
* @(#)vnode_if.sh 7.2 (Berkeley) %G%
struct vnodeop_desc vop_default_desc = {
# Awk script to take vnode_if.src and turn it into vnode_if.c.
# get the function arguments
# Print out the vop_F_vp_offsets structure. This all depends
# on naming conventions and nothing else.
printf("int %s_vp_offsets[] = {\n", name);
for (c2 = 0; c2 < c1; ++c2) {
if (c3 != 4 || t[1] !~ /^IN$/ || t[2] !~ /^struct$/ ||
t[3] !~ /^vnode$/ || t[4] !~ /.*vp;$/)
beg = match(t[c3], "[^*]");
printf("\tVOPARG_OFFSETOF(struct %s_args, a_%s),\n",
name, substr(t[4], beg, end - beg));
printf("\tVDESC_NO_OFFSET\n};\n");
# Print out the vnodeop_desc structure.
printf("struct vnodeop_desc %s_desc = {\n", name);
printf("\t0,\n\t\"%s\",\n\t0,\n\t%s_vp_offsets,\n", name, name);
# Print out return vpp entry, if any.
for (found = c2 = 0; c2 < c1; ++c2) {
if (c3 != 4 || t[1] !~ /^OUT$/ || t[2] !~ /^struct$/ ||
printf("\tVOPARG_OFFSETOF(struct %s_args, a_vpp),\n",
printf("\tVDESC_NO_OFFSET,\n");
# Print out cred entry, if any.
for (found = c2 = 0; c2 < c1; ++c2) {
if (c3 != 4 || t[1] !~ /^IN$/ || t[2] !~ /^struct$/ ||
printf("\tVOPARG_OFFSETOF(struct %s_args, a_cred),\n",
printf("\tVDESC_NO_OFFSET,\n");
# Print out proc entry, if any.
for (found = c2 = 0; c2 < c1; ++c2) {
if (c3 != 4 || t[1] !~ /^IN$/ || t[2] !~ /^struct$/ ||
printf("\tVOPARG_OFFSETOF(struct %s_args, a_p),\n",
printf("\tVDESC_NO_OFFSET,\n");
# THINGS THAT DON'T WORK RIGHT YET.
# Two existing BSD vnodeops (bwrite and strategy) don't take any vnodes as
# arguments. This means that these operations can't function successfully
# through a bypass routine.
# Bwrite and strategy will be replaced when the VM page/buffer cache
# To get around this problem for now we handle these ops as special cases.
cat << END_OF_SPECIAL_CASES >> $HEADER
struct vop_strategy_args {
struct vnodeop_desc *a_desc;
extern struct vnodeop_desc vop_strategy_desc;
static inline int VOP_STRATEGY(bp)
struct vop_strategy_args a;
a.a_desc = VDESC(vop_strategy);
return (VCALL((bp)->b_vp, VOFFSET(vop_strategy), &a));
struct vnodeop_desc *a_desc;
extern struct vnodeop_desc vop_bwrite_desc;
static inline int VOP_BWRITE(bp)
struct vop_bwrite_args a;
a.a_desc = VDESC(vop_bwrite);
return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a));
cat << END_OF_SPECIAL_CASES >> $CFILE
int vop_strategy_vp_offsets[] = {
struct vnodeop_desc vop_strategy_desc = {
int vop_bwrite_vp_offsets[] = {
struct vnodeop_desc vop_bwrite_desc = {
# Add the vfs_op_descs array to the C file.
printf("struct vnodeop_desc *vfs_op_descs[] = {\n");
printf("\t&vop_default_desc, /* MUST BE FIRST */\n");
printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n");
printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n");
printf("\t&%s_desc,\n", $1);
# Skip the function arguments.