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# @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
35# $Id: vnode_if.sh,v 1.4 1995/08/01 18:50:40 davidg 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
48if [ $# -ne 1 ] ; then
49 echo 'usage: vnode_if.sh srcfile'
50 exit 1
51fi
52
53# Name of the source file.
54SRC=$1
55
56# Names of the created files.
57CFILE=vnode_if.c
58HEADER=vnode_if.h
59
60# Awk program (must support nawk extensions and gawk's "toupper")
61# Use "awk" at Berkeley, "gawk" elsewhere.
62AWK=awk
63
64# Print out header information for vnode_if.h.
65cat << 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
73extern struct vnodeop_desc vop_default_desc;
74
75#include <vm/vm.h>
76#include <vm/vm_page.h>
77END_OF_LEADING_COMMENT
78
79# Awk script to take vnode_if.src and turn it into vnode_if.h.
80$AWK '
81 NF == 0 || $0 ~ "^#" {
82 next;
83 }
84 {
85 # Get the function name.
86 name = $1;
87 uname = toupper(name);
88
89 # Get the function arguments.
90 for (c1 = 0;; ++c1) {
91 if (getline <= 0)
92 exit
93 if ($0 ~ "^};")
94 break;
95 a[c1] = $0;
96 }
97
98 # Print out the vop_F_args structure.
99 printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n",
100 name);
101 for (c2 = 0; c2 < c1; ++c2) {
102 c3 = split(a[c2], t);
103 printf("\t");
104 if (t[2] ~ "WILLRELE")
105 c4 = 3;
106 else
107 c4 = 2;
108 for (; c4 < c3; ++c4)
109 printf("%s ", t[c4]);
110 beg = match(t[c3], "[^*]");
111 printf("%sa_%s\n",
112 substr(t[c4], 0, beg - 1), substr(t[c4], beg));
113 }
114 printf("};\n");
115
116 # Print out extern declaration.
117 printf("extern struct vnodeop_desc %s_desc;\n", name);
118
119 # Print out inline struct.
120 printf("static inline int %s(", uname);
121 sep = ", ";
122 for (c2 = 0; c2 < c1; ++c2) {
123 if (c2 == c1 - 1)
124 sep = ")\n";
125 c3 = split(a[c2], t);
126 beg = match(t[c3], "[^*]");
127 end = match(t[c3], ";");
128 printf("%s%s", substr(t[c3], beg, end - beg), sep);
129 }
130 for (c2 = 0; c2 < c1; ++c2) {
131 c3 = split(a[c2], t);
132 printf("\t");
133 if (t[2] ~ "WILLRELE")
134 c4 = 3;
135 else
136 c4 = 2;
137 for (; c4 < c3; ++c4)
138 printf("%s ", t[c4]);
139 beg = match(t[c3], "[^*]");
140 printf("%s%s\n",
141 substr(t[c4], 0, beg - 1), substr(t[c4], beg));
142 }
143 printf("{\n\tstruct %s_args a;\n\n", name);
144 printf("\ta.a_desc = VDESC(%s);\n", name);
145 for (c2 = 0; c2 < c1; ++c2) {
146 c3 = split(a[c2], t);
147 printf("\t");
148 beg = match(t[c3], "[^*]");
149 end = match(t[c3], ";");
150 printf("a.a_%s = %s\n",
151 substr(t[c3], beg, end - beg), substr(t[c3], beg));
152 }
153 c1 = split(a[0], t);
154 beg = match(t[c1], "[^*]");
155 end = match(t[c1], ";");
156 printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n",
157 substr(t[c1], beg, end - beg), name);
158 }' < $SRC >> $HEADER
159
160# Print out header information for vnode_if.c.
161cat << END_OF_LEADING_COMMENT > $CFILE
162/*
163 * This file is produced automatically.
164 * Do not modify anything in here by hand.
165 *
166 * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
167 */
168
169#include <sys/param.h>
170#include <sys/mount.h>
171#include <sys/vnode.h>
172#include <vm/vm.h>
173#include <vm/vm_page.h>
174
175struct vnodeop_desc vop_default_desc = {
176 0,
177 "default",
178 0,
179 NULL,
180 VDESC_NO_OFFSET,
181 VDESC_NO_OFFSET,
182 VDESC_NO_OFFSET,
183 VDESC_NO_OFFSET,
184 NULL,
185};
186
187END_OF_LEADING_COMMENT
188
189# Awk script to take vnode_if.src and turn it into vnode_if.c.
190$AWK 'function kill_surrounding_ws (s) {
191 sub (/^[ \t]*/, "", s);
192 sub (/[ \t]*$/, "", s);
193 return s;
194 }
195
196 function read_args() {
197 numargs = 0;
198 while (getline ln) {
199 if (ln ~ /}/) {
200 break;
201 };
202
203 # Delete comments, if any.
204 gsub (/\/\*.*\*\//, "", ln);
205
206 # Delete leading/trailing space.
207 ln = kill_surrounding_ws(ln);
208
209 # Pick off direction.
210 if (1 == sub(/^INOUT[ \t]+/, "", ln))
211 dir = "INOUT";
212 else if (1 == sub(/^IN[ \t]+/, "", ln))
213 dir = "IN";
214 else if (1 == sub(/^OUT[ \t]+/, "", ln))
215 dir = "OUT";
216 else
217 bail("No IN/OUT direction for \"" ln "\".");
218
219 # check for "WILLRELE"
220 if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) {
221 rele = "WILLRELE";
222 } else {
223 rele = "WONTRELE";
224 };
225
226 # kill trailing ;
227 if (1 != sub (/;$/, "", ln)) {
228 bail("Missing end-of-line ; in \"" ln "\".");
229 };
230
231 # pick off variable name
232 if (!(i = match(ln, /[A-Za-z0-9_]+$/))) {
233 bail("Missing var name \"a_foo\" in \"" ln "\".");
234 };
235 arg = substr (ln, i);
236 # Want to <<substr(ln, i) = "";>>, but nawk cannot.
237 # Hack around this.
238 ln = substr(ln, 1, i-1);
239
240 # what is left must be type
241 # (put clean it up some)
242 type = ln;
243 gsub (/[ \t]+/, " ", type); # condense whitespace
244 type = kill_surrounding_ws(type);
245
246 # (boy this was easier in Perl)
247
248 numargs++;
249 dirs[numargs] = dir;
250 reles[numargs] = rele;
251 types[numargs] = type;
252 args[numargs] = arg;
253 };
254 }
255
256 function generate_operation_vp_offsets() {
257 printf ("int %s_vp_offsets[] = {\n", name);
258 # as a side effect, figure out the releflags
259 releflags = "";
260 vpnum = 0;
261 for (i=1; i<=numargs; i++) {
262 if (types[i] == "struct vnode *") {
263 printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
264 name, args[i]);
265 if (reles[i] == "WILLRELE") {
266 releflags = releflags "|VDESC_VP" vpnum "_WILLRELE";
267 };
268 vpnum++;
269 };
270 };
271 sub (/^\|/, "", releflags);
272 print "\tVDESC_NO_OFFSET";
273 print "};";
274 }
275
276 function find_arg_with_type (type) {
277 for (i=1; i<=numargs; i++) {
278 if (types[i] == type) {
279 return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")";
280 };
281 };
282 return "VDESC_NO_OFFSET";
283 }
284
285 function generate_operation_desc() {
286 printf ("struct vnodeop_desc %s_desc = {\n", name);
287 # offset
288 printf ("\t0,\n");
289 # printable name
290 printf ("\t\"%s\",\n", name);
291 # flags
292 vppwillrele = "";
293 for (i=1; i<=numargs; i++) {
294 if (types[i] == "struct vnode **" &&
295 (reles[i] == "WILLRELE")) {
296 vppwillrele = "|VDESC_VPP_WILLRELE";
297 };
298 };
299 if (releflags == "") {
300 printf ("\t0%s,\n", vppwillrele);
301 } else {
302 printf ("\t%s%s,\n", releflags, vppwillrele);
303 };
304 # vp offsets
305 printf ("\t%s_vp_offsets,\n", name);
306 # vpp (if any)
307 printf ("\t%s,\n", find_arg_with_type("struct vnode **"));
308 # cred (if any)
309 printf ("\t%s,\n", find_arg_with_type("struct ucred *"));
310 # proc (if any)
311 printf ("\t%s,\n", find_arg_with_type("struct proc *"));
312 # componentname
313 printf ("\t%s,\n", find_arg_with_type("struct componentname *"));
314 # transport layer information
315 printf ("\tNULL,\n};\n");
316 }
317
318 NF == 0 || $0 ~ "^#" {
319 next;
320 }
321 {
322 # get the function name
323 name = $1;
324
325 # get the function arguments
326 read_args();
327
328 # Print out the vop_F_vp_offsets structure. This all depends
329 # on naming conventions and nothing else.
330 generate_operation_vp_offsets();
331
332 # Print out the vnodeop_desc structure.
333 generate_operation_desc();
334
335 printf "\n";
336
337 }' < $SRC >> $CFILE
338# THINGS THAT DON'T WORK RIGHT YET.
339#
340# Two existing BSD vnodeops (bwrite and strategy) don't take any vnodes as
341# arguments. This means that these operations can't function successfully
342# through a bypass routine.
343#
344# Bwrite and strategy will be replaced when the VM page/buffer cache
345# integration happens.
346#
347# To get around this problem for now we handle these ops as special cases.
348
349cat << END_OF_SPECIAL_CASES >> $HEADER
350#include <sys/buf.h>
351struct vop_strategy_args {
352 struct vnodeop_desc *a_desc;
353 struct buf *a_bp;
354};
355extern struct vnodeop_desc vop_strategy_desc;
356static inline int VOP_STRATEGY(bp)
357 struct buf *bp;
358{
359 struct vop_strategy_args a;
360
361 a.a_desc = VDESC(vop_strategy);
362 a.a_bp = bp;
363 return (VCALL((bp)->b_vp, VOFFSET(vop_strategy), &a));
364}
365
366struct vop_bwrite_args {
367 struct vnodeop_desc *a_desc;
368 struct buf *a_bp;
369};
370extern struct vnodeop_desc vop_bwrite_desc;
371static inline int VOP_BWRITE(bp)
372 struct buf *bp;
373{
374 struct vop_bwrite_args a;
375
376 a.a_desc = VDESC(vop_bwrite);
377 a.a_bp = bp;
378 return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a));
379}
380END_OF_SPECIAL_CASES
381
382cat << END_OF_SPECIAL_CASES >> $CFILE
383int vop_strategy_vp_offsets[] = {
384 VDESC_NO_OFFSET
385};
386struct vnodeop_desc vop_strategy_desc = {
387 0,
388 "vop_strategy",
389 0,
390 vop_strategy_vp_offsets,
391 VDESC_NO_OFFSET,
392 VDESC_NO_OFFSET,
393 VDESC_NO_OFFSET,
394 VDESC_NO_OFFSET,
395 NULL,
396};
397int vop_bwrite_vp_offsets[] = {
398 VDESC_NO_OFFSET
399};
400struct vnodeop_desc vop_bwrite_desc = {
401 0,
402 "vop_bwrite",
403 0,
404 vop_bwrite_vp_offsets,
405 VDESC_NO_OFFSET,
406 VDESC_NO_OFFSET,
407 VDESC_NO_OFFSET,
408 VDESC_NO_OFFSET,
409 NULL,
410};
411END_OF_SPECIAL_CASES
412
413# Add the vfs_op_descs array to the C file.
414$AWK '
415 BEGIN {
416 printf("\nstruct vnodeop_desc *vfs_op_descs[] = {\n");
417 printf("\t&vop_default_desc, /* MUST BE FIRST */\n");
418 printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n");
419 printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n");
420 }
421 END {
422 printf("\tNULL\n};\n");
423 }
424 NF == 0 || $0 ~ "^#" {
425 next;
426 }
427 {
428 # Get the function name.
429 printf("\t&%s_desc,\n", $1);
430
431 # Skip the function arguments.
432 for (;;) {
433 if (getline <= 0)
434 exit
435 if ($0 ~ "^};")
436 break;
437 }
438 }' < $SRC >> $CFILE
439
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# @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
35# $Id: vnode_if.sh,v 1.4 1995/08/01 18:50:40 davidg 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
48if [ $# -ne 1 ] ; then
49 echo 'usage: vnode_if.sh srcfile'
50 exit 1
51fi
52
53# Name of the source file.
54SRC=$1
55
56# Names of the created files.
57CFILE=vnode_if.c
58HEADER=vnode_if.h
59
60# Awk program (must support nawk extensions and gawk's "toupper")
61# Use "awk" at Berkeley, "gawk" elsewhere.
62AWK=awk
63
64# Print out header information for vnode_if.h.
65cat << 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
73extern struct vnodeop_desc vop_default_desc;
74
75#include <vm/vm.h>
76#include <vm/vm_page.h>
77END_OF_LEADING_COMMENT
78
79# Awk script to take vnode_if.src and turn it into vnode_if.h.
80$AWK '
81 NF == 0 || $0 ~ "^#" {
82 next;
83 }
84 {
85 # Get the function name.
86 name = $1;
87 uname = toupper(name);
88
89 # Get the function arguments.
90 for (c1 = 0;; ++c1) {
91 if (getline <= 0)
92 exit
93 if ($0 ~ "^};")
94 break;
95 a[c1] = $0;
96 }
97
98 # Print out the vop_F_args structure.
99 printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n",
100 name);
101 for (c2 = 0; c2 < c1; ++c2) {
102 c3 = split(a[c2], t);
103 printf("\t");
104 if (t[2] ~ "WILLRELE")
105 c4 = 3;
106 else
107 c4 = 2;
108 for (; c4 < c3; ++c4)
109 printf("%s ", t[c4]);
110 beg = match(t[c3], "[^*]");
111 printf("%sa_%s\n",
112 substr(t[c4], 0, beg - 1), substr(t[c4], beg));
113 }
114 printf("};\n");
115
116 # Print out extern declaration.
117 printf("extern struct vnodeop_desc %s_desc;\n", name);
118
119 # Print out inline struct.
120 printf("static inline int %s(", uname);
121 sep = ", ";
122 for (c2 = 0; c2 < c1; ++c2) {
123 if (c2 == c1 - 1)
124 sep = ")\n";
125 c3 = split(a[c2], t);
126 beg = match(t[c3], "[^*]");
127 end = match(t[c3], ";");
128 printf("%s%s", substr(t[c3], beg, end - beg), sep);
129 }
130 for (c2 = 0; c2 < c1; ++c2) {
131 c3 = split(a[c2], t);
132 printf("\t");
133 if (t[2] ~ "WILLRELE")
134 c4 = 3;
135 else
136 c4 = 2;
137 for (; c4 < c3; ++c4)
138 printf("%s ", t[c4]);
139 beg = match(t[c3], "[^*]");
140 printf("%s%s\n",
141 substr(t[c4], 0, beg - 1), substr(t[c4], beg));
142 }
143 printf("{\n\tstruct %s_args a;\n\n", name);
144 printf("\ta.a_desc = VDESC(%s);\n", name);
145 for (c2 = 0; c2 < c1; ++c2) {
146 c3 = split(a[c2], t);
147 printf("\t");
148 beg = match(t[c3], "[^*]");
149 end = match(t[c3], ";");
150 printf("a.a_%s = %s\n",
151 substr(t[c3], beg, end - beg), substr(t[c3], beg));
152 }
153 c1 = split(a[0], t);
154 beg = match(t[c1], "[^*]");
155 end = match(t[c1], ";");
156 printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n",
157 substr(t[c1], beg, end - beg), name);
158 }' < $SRC >> $HEADER
159
160# Print out header information for vnode_if.c.
161cat << END_OF_LEADING_COMMENT > $CFILE
162/*
163 * This file is produced automatically.
164 * Do not modify anything in here by hand.
165 *
166 * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
167 */
168
169#include <sys/param.h>
170#include <sys/mount.h>
171#include <sys/vnode.h>
172#include <vm/vm.h>
173#include <vm/vm_page.h>
174
175struct vnodeop_desc vop_default_desc = {
176 0,
177 "default",
178 0,
179 NULL,
180 VDESC_NO_OFFSET,
181 VDESC_NO_OFFSET,
182 VDESC_NO_OFFSET,
183 VDESC_NO_OFFSET,
184 NULL,
185};
186
187END_OF_LEADING_COMMENT
188
189# Awk script to take vnode_if.src and turn it into vnode_if.c.
190$AWK 'function kill_surrounding_ws (s) {
191 sub (/^[ \t]*/, "", s);
192 sub (/[ \t]*$/, "", s);
193 return s;
194 }
195
196 function read_args() {
197 numargs = 0;
198 while (getline ln) {
199 if (ln ~ /}/) {
200 break;
201 };
202
203 # Delete comments, if any.
204 gsub (/\/\*.*\*\//, "", ln);
205
206 # Delete leading/trailing space.
207 ln = kill_surrounding_ws(ln);
208
209 # Pick off direction.
210 if (1 == sub(/^INOUT[ \t]+/, "", ln))
211 dir = "INOUT";
212 else if (1 == sub(/^IN[ \t]+/, "", ln))
213 dir = "IN";
214 else if (1 == sub(/^OUT[ \t]+/, "", ln))
215 dir = "OUT";
216 else
217 bail("No IN/OUT direction for \"" ln "\".");
218
219 # check for "WILLRELE"
220 if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) {
221 rele = "WILLRELE";
222 } else {
223 rele = "WONTRELE";
224 };
225
226 # kill trailing ;
227 if (1 != sub (/;$/, "", ln)) {
228 bail("Missing end-of-line ; in \"" ln "\".");
229 };
230
231 # pick off variable name
232 if (!(i = match(ln, /[A-Za-z0-9_]+$/))) {
233 bail("Missing var name \"a_foo\" in \"" ln "\".");
234 };
235 arg = substr (ln, i);
236 # Want to <<substr(ln, i) = "";>>, but nawk cannot.
237 # Hack around this.
238 ln = substr(ln, 1, i-1);
239
240 # what is left must be type
241 # (put clean it up some)
242 type = ln;
243 gsub (/[ \t]+/, " ", type); # condense whitespace
244 type = kill_surrounding_ws(type);
245
246 # (boy this was easier in Perl)
247
248 numargs++;
249 dirs[numargs] = dir;
250 reles[numargs] = rele;
251 types[numargs] = type;
252 args[numargs] = arg;
253 };
254 }
255
256 function generate_operation_vp_offsets() {
257 printf ("int %s_vp_offsets[] = {\n", name);
258 # as a side effect, figure out the releflags
259 releflags = "";
260 vpnum = 0;
261 for (i=1; i<=numargs; i++) {
262 if (types[i] == "struct vnode *") {
263 printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
264 name, args[i]);
265 if (reles[i] == "WILLRELE") {
266 releflags = releflags "|VDESC_VP" vpnum "_WILLRELE";
267 };
268 vpnum++;
269 };
270 };
271 sub (/^\|/, "", releflags);
272 print "\tVDESC_NO_OFFSET";
273 print "};";
274 }
275
276 function find_arg_with_type (type) {
277 for (i=1; i<=numargs; i++) {
278 if (types[i] == type) {
279 return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")";
280 };
281 };
282 return "VDESC_NO_OFFSET";
283 }
284
285 function generate_operation_desc() {
286 printf ("struct vnodeop_desc %s_desc = {\n", name);
287 # offset
288 printf ("\t0,\n");
289 # printable name
290 printf ("\t\"%s\",\n", name);
291 # flags
292 vppwillrele = "";
293 for (i=1; i<=numargs; i++) {
294 if (types[i] == "struct vnode **" &&
295 (reles[i] == "WILLRELE")) {
296 vppwillrele = "|VDESC_VPP_WILLRELE";
297 };
298 };
299 if (releflags == "") {
300 printf ("\t0%s,\n", vppwillrele);
301 } else {
302 printf ("\t%s%s,\n", releflags, vppwillrele);
303 };
304 # vp offsets
305 printf ("\t%s_vp_offsets,\n", name);
306 # vpp (if any)
307 printf ("\t%s,\n", find_arg_with_type("struct vnode **"));
308 # cred (if any)
309 printf ("\t%s,\n", find_arg_with_type("struct ucred *"));
310 # proc (if any)
311 printf ("\t%s,\n", find_arg_with_type("struct proc *"));
312 # componentname
313 printf ("\t%s,\n", find_arg_with_type("struct componentname *"));
314 # transport layer information
315 printf ("\tNULL,\n};\n");
316 }
317
318 NF == 0 || $0 ~ "^#" {
319 next;
320 }
321 {
322 # get the function name
323 name = $1;
324
325 # get the function arguments
326 read_args();
327
328 # Print out the vop_F_vp_offsets structure. This all depends
329 # on naming conventions and nothing else.
330 generate_operation_vp_offsets();
331
332 # Print out the vnodeop_desc structure.
333 generate_operation_desc();
334
335 printf "\n";
336
337 }' < $SRC >> $CFILE
338# THINGS THAT DON'T WORK RIGHT YET.
339#
340# Two existing BSD vnodeops (bwrite and strategy) don't take any vnodes as
341# arguments. This means that these operations can't function successfully
342# through a bypass routine.
343#
344# Bwrite and strategy will be replaced when the VM page/buffer cache
345# integration happens.
346#
347# To get around this problem for now we handle these ops as special cases.
348
349cat << END_OF_SPECIAL_CASES >> $HEADER
350#include <sys/buf.h>
351struct vop_strategy_args {
352 struct vnodeop_desc *a_desc;
353 struct buf *a_bp;
354};
355extern struct vnodeop_desc vop_strategy_desc;
356static inline int VOP_STRATEGY(bp)
357 struct buf *bp;
358{
359 struct vop_strategy_args a;
360
361 a.a_desc = VDESC(vop_strategy);
362 a.a_bp = bp;
363 return (VCALL((bp)->b_vp, VOFFSET(vop_strategy), &a));
364}
365
366struct vop_bwrite_args {
367 struct vnodeop_desc *a_desc;
368 struct buf *a_bp;
369};
370extern struct vnodeop_desc vop_bwrite_desc;
371static inline int VOP_BWRITE(bp)
372 struct buf *bp;
373{
374 struct vop_bwrite_args a;
375
376 a.a_desc = VDESC(vop_bwrite);
377 a.a_bp = bp;
378 return (VCALL((bp)->b_vp, VOFFSET(vop_bwrite), &a));
379}
380END_OF_SPECIAL_CASES
381
382cat << END_OF_SPECIAL_CASES >> $CFILE
383int vop_strategy_vp_offsets[] = {
384 VDESC_NO_OFFSET
385};
386struct vnodeop_desc vop_strategy_desc = {
387 0,
388 "vop_strategy",
389 0,
390 vop_strategy_vp_offsets,
391 VDESC_NO_OFFSET,
392 VDESC_NO_OFFSET,
393 VDESC_NO_OFFSET,
394 VDESC_NO_OFFSET,
395 NULL,
396};
397int vop_bwrite_vp_offsets[] = {
398 VDESC_NO_OFFSET
399};
400struct vnodeop_desc vop_bwrite_desc = {
401 0,
402 "vop_bwrite",
403 0,
404 vop_bwrite_vp_offsets,
405 VDESC_NO_OFFSET,
406 VDESC_NO_OFFSET,
407 VDESC_NO_OFFSET,
408 VDESC_NO_OFFSET,
409 NULL,
410};
411END_OF_SPECIAL_CASES
412
413# Add the vfs_op_descs array to the C file.
414$AWK '
415 BEGIN {
416 printf("\nstruct vnodeop_desc *vfs_op_descs[] = {\n");
417 printf("\t&vop_default_desc, /* MUST BE FIRST */\n");
418 printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n");
419 printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n");
420 }
421 END {
422 printf("\tNULL\n};\n");
423 }
424 NF == 0 || $0 ~ "^#" {
425 next;
426 }
427 {
428 # Get the function name.
429 printf("\t&%s_desc,\n", $1);
430
431 # Skip the function arguments.
432 for (;;) {
433 if (getline <= 0)
434 exit
435 if ($0 ~ "^};")
436 break;
437 }
438 }' < $SRC >> $CFILE
439