summaryrefslogtreecommitdiffstats
path: root/xlators/features/metadisp/src/gen-fops.py
blob: 8b5e120fdecf844538580f6db875a76059a0809b (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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/python

import sys
from generator import fop_subs, generate

FN_METADATA_CHILD_GENERIC = """
int32_t
metadisp_@NAME@ (call_frame_t *frame, xlator_t *this,
                 @LONG_ARGS@)
{
  METADISP_TRACE("@NAME@ metadata");
  STACK_WIND (frame, default_@NAME@_cbk,
              METADATA_CHILD(this), METADATA_CHILD(this)->fops->@NAME@,
              @SHORT_ARGS@);
  return 0;
}
"""

FN_GENERIC_TEMPLATE = """
int32_t
metadisp_@NAME@ (call_frame_t *frame, xlator_t *this,
                          @LONG_ARGS@)
{
  METADISP_TRACE("@NAME@ generic");
  STACK_WIND (frame, default_@NAME@_cbk,
                          DATA_CHILD(this), DATA_CHILD(this)->fops->@NAME@,
                          @SHORT_ARGS@);
  return 0;
}
"""

FN_DATAFD_TEMPLATE = """
int32_t
metadisp_@NAME@ (call_frame_t *frame, xlator_t *this,
                          @LONG_ARGS@)
{
  METADISP_TRACE("@NAME@ datafd");
  xlator_t *child = NULL;
  child = DATA_CHILD(this);
  STACK_WIND (frame, default_@NAME@_cbk,
                          child, child->fops->@NAME@,
                          @SHORT_ARGS@);
  return 0;
}
"""

FN_DATALOC_TEMPLATE = """
int32_t
metadisp_@NAME@ (call_frame_t *frame, xlator_t *this,
                          @LONG_ARGS@)
{
  METADISP_TRACE("@NAME@ dataloc");
  loc_t backend_loc = {
      0,
  };
  if (build_backend_loc(loc->gfid, loc, &backend_loc)) {
      goto unwind;
  }
  xlator_t *child = NULL;
  child = DATA_CHILD(this);
  STACK_WIND (frame, default_@NAME@_cbk,
                          child, child->fops->@NAME@,
                          @SHORT_ARGS@);
  return 0;

unwind:
  STACK_UNWIND_STRICT(lookup, frame, -1, EINVAL, NULL, NULL, NULL, NULL);
  return 0;
}
"""

FOPS_LINE_TEMPLATE = "\t.@NAME@ = metadisp_@NAME@,"

skipped = [
    "readdir",
    "readdirp",
    "lookup",
    "fsync",
    "stat",
    "open",
    "create",
    "unlink",
    "setattr",
    # TODO: implement "inodelk",
]


def gen_fops():
    done = skipped

    #
    # these are fops that wind to the DATA_CHILD
    #
    # NOTE: re-written in order from google doc:
    #          https://docs.google.com/document/d/1KEwVtSNvDhs4qb63gWx2ulCp5GJjge77NGJk4p_Ms4Q
    for name in [
        "writev",
        "readv",
        "ftruncate",
        "zerofill",
        "discard",
        "seek",
        "fstat",
    ]:
        done = done + [name]
        print(generate(FN_DATAFD_TEMPLATE, name, fop_subs))

    for name in ["truncate"]:
        done = done + [name]
        print(generate(FN_DATALOC_TEMPLATE, name, fop_subs))

    # these are fops that operate solely on dentries, folders,
    # or extended attributes. Therefore, they must always
    # wind to METADATA_CHILD and should never perform
    # any path rewriting
    #
    # NOTE: re-written in order from google doc:
    #          https://docs.google.com/document/d/1KEwVtSNvDhs4qb63gWx2ulCp5GJjge77NGJk4p_Ms4Q
    for name in [
        "mkdir",
        "symlink",
        "link",
        "rename",
        "mknod",
        "opendir",
        # "readdir,  # special-cased
        # "readdirp, # special-cased
        "fsyncdir",
        # "setattr", # special-cased
        "readlink",
        "fentrylk",
        "access",
        # TODO: these wind to both,
        # data for backend-attributes and metadata for the rest
        "xattrop",
        "setxattr",
        "getxattr",
        "removexattr",
        "fgetxattr",
        "fsetxattr",
        "fremovexattr",
    ]:

        done = done + [name]
        print(generate(FN_METADATA_CHILD_GENERIC, name, fop_subs))

    print("struct xlator_fops fops = {")
    for name in done:
        print(generate(FOPS_LINE_TEMPLATE, name, fop_subs))

    print("};")


for l in open(sys.argv[1], "r").readlines():
    if l.find("#pragma generate") != -1:
        print("/* BEGIN GENERATED CODE - DO NOT MODIFY */")
        gen_fops()
        print("/* END GENERATED CODE */")
    else:
        print(l[:-1])