]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcache/opts.c
Delete more unused shim code, update bcache code
[bcachefs-tools-debian] / libbcache / opts.c
1
2 #include <linux/kernel.h>
3
4 #include "opts.h"
5 #include "util.h"
6
7 const char * const bch_error_actions[] = {
8         "continue",
9         "remount-ro",
10         "panic",
11         NULL
12 };
13
14 const char * const bch_csum_types[] = {
15         "none",
16         "crc32c",
17         "crc64",
18         NULL
19 };
20
21 const char * const bch_compression_types[] = {
22         "none",
23         "lz4",
24         "gzip",
25         NULL
26 };
27
28 const char * const bch_str_hash_types[] = {
29         "crc32c",
30         "crc64",
31         "siphash",
32         NULL
33 };
34
35 const char * const bch_cache_replacement_policies[] = {
36         "lru",
37         "fifo",
38         "random",
39         NULL
40 };
41
42 /* Default is -1; we skip past it for struct cached_dev's cache mode */
43 const char * const bch_cache_modes[] = {
44         "default",
45         "writethrough",
46         "writeback",
47         "writearound",
48         "none",
49         NULL
50 };
51
52 const char * const bch_dev_state[] = {
53         "active",
54         "readonly",
55         "failed",
56         "spare",
57         NULL
58 };
59
60 const struct bch_option bch_opt_table[] = {
61 #define OPT_BOOL()              .type = BCH_OPT_BOOL
62 #define OPT_UINT(_min, _max)    .type = BCH_OPT_UINT, .min = _min, .max = _max
63 #define OPT_STR(_choices)       .type = BCH_OPT_STR, .choices = _choices
64
65 #define BCH_OPT(_name, _mode, _sb_opt, _bits, _type)                    \
66         [Opt_##_name] = {                                               \
67                 .name   = #_name,                                       \
68                 .set_sb = SET_##_sb_opt,                                \
69                 _type                                                   \
70         },
71         BCH_VISIBLE_OPTS()
72 #undef BCH_OPT
73 };
74
75 static enum bch_opt_id bch_opt_lookup(const char *name)
76 {
77         const struct bch_option *i;
78
79         for (i = bch_opt_table;
80              i < bch_opt_table + ARRAY_SIZE(bch_opt_table);
81              i++)
82                 if (!strcmp(name, i->name))
83                         return i - bch_opt_table;
84
85         return -1;
86 }
87
88 static u64 bch_opt_get(struct bch_opts *opts, enum bch_opt_id id)
89 {
90         switch (id) {
91 #define BCH_OPT(_name, ...)                                             \
92         case Opt_##_name:                                               \
93                 return opts->_name;                                     \
94
95         BCH_VISIBLE_OPTS()
96 #undef BCH_OPT
97
98         default:
99                 BUG();
100         }
101 }
102
103 void bch_opt_set(struct bch_opts *opts, enum bch_opt_id id, u64 v)
104 {
105         switch (id) {
106 #define BCH_OPT(_name, ...)                                             \
107         case Opt_##_name:                                               \
108                 opts->_name = v;                                        \
109                 break;
110
111         BCH_VISIBLE_OPTS()
112 #undef BCH_OPT
113
114         default:
115                 BUG();
116         }
117 }
118
119 /*
120  * Initial options from superblock - here we don't want any options undefined,
121  * any options the superblock doesn't specify are set to 0:
122  */
123 struct bch_opts bch_sb_opts(struct bch_sb *sb)
124 {
125         struct bch_opts opts = bch_opts_empty();
126
127 #define BCH_OPT(_name, _mode, _sb_opt, ...)                             \
128         if (_sb_opt != NO_SB_OPT)                                       \
129                 opts._name = _sb_opt(sb);
130
131         BCH_OPTS()
132 #undef BCH_OPT
133
134         return opts;
135 }
136
137 int parse_one_opt(enum bch_opt_id id, const char *val, u64 *res)
138 {
139         const struct bch_option *opt = &bch_opt_table[id];
140         ssize_t ret;
141
142         switch (opt->type) {
143         case BCH_OPT_BOOL:
144                 ret = kstrtou64(val, 10, res);
145                 if (ret < 0)
146                         return ret;
147
148                 if (*res > 1)
149                         return -ERANGE;
150                 break;
151         case BCH_OPT_UINT:
152                 ret = kstrtou64(val, 10, res);
153                 if (ret < 0)
154                         return ret;
155
156                 if (*res < opt->min || *res >= opt->max)
157                         return -ERANGE;
158                 break;
159         case BCH_OPT_STR:
160                 ret = bch_read_string_list(val, opt->choices);
161                 if (ret < 0)
162                         return ret;
163
164                 *res = ret;
165                 break;
166         }
167
168         return 0;
169 }
170
171 int bch_parse_mount_opts(struct bch_opts *opts, char *options)
172 {
173         char *opt, *name, *val;
174         enum bch_opt_id id;
175         int ret;
176         u64 v;
177
178         while ((opt = strsep(&options, ",")) != NULL) {
179                 name    = strsep(&opt, "=");
180                 val     = opt;
181
182                 if (val) {
183                         id = bch_opt_lookup(name);
184                         if (id < 0)
185                                 return -EINVAL;
186
187                         ret = parse_one_opt(id, val, &v);
188                         if (ret < 0)
189                                 return ret;
190                 } else {
191                         id = bch_opt_lookup(name);
192                         v = 1;
193
194                         if (id < 0 &&
195                             !strncmp("no", name, 2)) {
196                                 id = bch_opt_lookup(name + 2);
197                                 v = 0;
198                         }
199
200                         if (bch_opt_table[id].type != BCH_OPT_BOOL)
201                                 return -EINVAL;
202                 }
203
204                 bch_opt_set(opts, id, v);
205         }
206
207         return 0;
208 }
209
210 enum bch_opt_id bch_parse_sysfs_opt(const char *name, const char *val,
211                                     u64 *res)
212 {
213         enum bch_opt_id id = bch_opt_lookup(name);
214         int ret;
215
216         if (id < 0)
217                 return -EINVAL;
218
219         ret = parse_one_opt(id, val, res);
220         if (ret < 0)
221                 return ret;
222
223         return id;
224 }
225
226 ssize_t bch_opt_show(struct bch_opts *opts, const char *name,
227                      char *buf, size_t size)
228 {
229         enum bch_opt_id id = bch_opt_lookup(name);
230         const struct bch_option *opt;
231         u64 v;
232
233         if (id < 0)
234                 return -EINVAL;
235
236         v = bch_opt_get(opts, id);
237         opt = &bch_opt_table[id];
238
239         return opt->type == BCH_OPT_STR
240                 ? bch_snprint_string_list(buf, size, opt->choices, v)
241                 : snprintf(buf, size, "%lli\n", v);
242 }