summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/nsr-server/src/gen-fops.py
blob: 1639f489ccb064ead764ff638a99fbd2093e12cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/python

# This script generates the boilerplate versions of most fops and cbks in the
# server.  This allows the details of leadership-status checking, sequencing
# between leader and followers (including fan-out), and basic error checking
# to be centralized one place, with per-operation code kept to a minimum.

import sys
import codegen

type_re = "([a-z_0-9]+)"
name_re = "\(\*fop_([a-z0-9]+)_t\)"
full_re = type_re + " *" + name_re
fop_cg = codegen.CodeGenerator()
fop_cg.skip = 2
fop_cg.parse_decls(sys.argv[1],full_re)
fop_cg.load_templates(sys.argv[2])

# Use the multi-template feature to generate multiple callbacks from the same
# parsed declarations.
type_re = "([a-z_0-9]+)"
name_re = "\(\*fop_([a-z0-9]+)_cbk_t\)"
full_re = type_re + " *" + name_re
cbk_cg = codegen.CodeGenerator()
cbk_cg.skip = 5
cbk_cg.parse_decls(sys.argv[1],full_re)
cbk_cg.load_templates(sys.argv[2])

# This is a nasty little trick to handle the case where a generated fop needs
# a set of default arguments for the corresponding callback.
fop_cg.make_defaults = cbk_cg.make_defaults

# We need two types of templates.  The first, for pure read operations, just
# needs to do a simple am-i-leader check (augmented to allow dirty reads).
# The second, for pure writes, needs to do fan-out to followers between those
# initial checks and local execution.  There are other operations that don't
# fit neatly into either category - e.g. lock ops or fsync - so we'll just have
# to handle those manually.  The table thus includes entries only for those we
# can categorize.  The special cases, plus any new operations we've never even
# heard of, aren't in there.
#
# Various keywords can be used to define/undefine preprocessor symbols used
# in the templates, on a per-function basis.  For example, if the keyword here
# is "fsync" (lowercase word or abbreviation) that will cause NSR_CG_FSYNC
# (prefix plus uppercase version) to be defined above all of the generated code
# for that fop.

fop_table = {
	"access":		"read",
	"create":		"write",
	"discard":		"write",
#	"entrylk":		"read",
	"fallocate":	"write",
#	"fentrylk":		"read",
	"fgetxattr":	"read",
#	"finodelk":		"read",
#	"flush":		"read",
	"fremovexattr":	"write",
	"fsetattr":		"write",
	"fsetxattr":	"write",
	"fstat":		"read",
#	"fsync":		"read",
#	"fsyncdir":		"read",
	"ftruncate":	"write",
	"fxattrop":		"write",
	"getxattr":		"read",
#	"inodelk":		"read",
	"link":			"write",
#	"lk":			"read",
#	"lookup":		"read",
	"mkdir":		"write",
	"mknod":		"write",
	"open":			"write",
	"opendir":		"read",
	"rchecksum":	"read",
	"readdir":		"read",
	"readdirp":		"read",
	"readlink":		"read",
	"readv":		"read",
	"removexattr":	"write",
	"rename":		"write",
	"rmdir":		"write",
	"setattr":		"write",
	"setxattr":		"write",
	"stat":			"read",
	"statfs":		"read",
	"symlink":		"write",
	"truncate":		"write",
	"unlink":		"write",
	"writev":		"write,fsync,queue",
	"xattrop":		"write",
}

fops_done = []
for x in sorted(fop_cg.decls.keys()):
	if x in fop_table.keys():
		info = fop_table[x].split(",")
		kind = info[0]
		flags = info[1:]
		if ("fsync" in flags) or ("queue" in flags):
			flags.append("need_fd")
		for fname in flags:
			print "#define NSR_CG_%s" % fname.upper()
		cbk_cg.emit(x,kind+"-complete")
		fop_cg.emit(x,kind+"-continue")
		cbk_cg.emit(x,kind+"-fan-in")
		fop_cg.emit(x,kind+"-dispatch")
		fop_cg.emit(x,kind+"-fop")
		for fname in flags:
			print "#undef NSR_CG_%s" % fname.upper()
		fops_done.append(x)
	else:
		print("/* No code emitted for %s */"%x)
		print("")

# Just for fun, emit the fops table too.
print("struct xlator_fops fops = {")
for x in fops_done:
	print("	.%s = nsr_%s,"%(x,x))
print("};")