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