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