1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/kernel.h>
7 #include "disk_groups.h"
14 const char * const bch2_error_actions[] = {
19 const char * const bch2_sb_features[] = {
24 const char * const bch2_sb_compat[] = {
29 const char * const bch2_btree_ids[] = {
34 const char * const bch2_csum_opts[] = {
39 const char * const bch2_compression_opts[] = {
40 BCH_COMPRESSION_OPTS()
44 const char * const bch2_str_hash_types[] = {
49 const char * const bch2_data_types[] = {
54 const char * const bch2_cache_replacement_policies[] = {
55 BCH_CACHE_REPLACEMENT_POLICIES()
59 const char * const bch2_member_states[] = {
66 void bch2_opts_apply(struct bch_opts *dst, struct bch_opts src)
68 #define x(_name, ...) \
69 if (opt_defined(src, _name)) \
70 opt_set(*dst, _name, src._name);
76 bool bch2_opt_defined_by_id(const struct bch_opts *opts, enum bch_opt_id id)
79 #define x(_name, ...) \
81 return opt_defined(*opts, _name);
89 u64 bch2_opt_get_by_id(const struct bch_opts *opts, enum bch_opt_id id)
92 #define x(_name, ...) \
102 void bch2_opt_set_by_id(struct bch_opts *opts, enum bch_opt_id id, u64 v)
105 #define x(_name, ...) \
107 opt_set(*opts, _name, v); \
117 * Initial options from superblock - here we don't want any options undefined,
118 * any options the superblock doesn't specify are set to 0:
120 struct bch_opts bch2_opts_from_sb(struct bch_sb *sb)
122 struct bch_opts opts = bch2_opts_empty();
124 #define x(_name, _bits, _mode, _type, _sb_opt, ...) \
125 if (_sb_opt != NO_SB_OPT) \
126 opt_set(opts, _name, _sb_opt(sb));
133 const struct bch_option bch2_opt_table[] = {
134 #define OPT_BOOL() .type = BCH_OPT_BOOL
135 #define OPT_UINT(_min, _max) .type = BCH_OPT_UINT, .min = _min, .max = _max
136 #define OPT_SECTORS(_min, _max) .type = BCH_OPT_SECTORS, .min = _min, .max = _max
137 #define OPT_STR(_choices) .type = BCH_OPT_STR, .choices = _choices
138 #define OPT_FN(_fn) .type = BCH_OPT_FN, \
139 .parse = _fn##_parse, \
140 .to_text = _fn##_to_text
142 #define x(_name, _bits, _mode, _type, _sb_opt, _default, _hint, _help) \
146 .mode = (_mode) & OPT_RUNTIME ? 0644 : 0444, \
151 .set_sb = SET_##_sb_opt, \
159 int bch2_opt_lookup(const char *name)
161 const struct bch_option *i;
163 for (i = bch2_opt_table;
164 i < bch2_opt_table + ARRAY_SIZE(bch2_opt_table);
166 if (!strcmp(name, i->attr.name))
167 return i - bch2_opt_table;
176 static const struct synonym bch_opt_synonyms[] = {
177 { "quota", "usrquota" },
180 static int bch2_mount_opt_lookup(const char *name)
182 const struct synonym *i;
184 for (i = bch_opt_synonyms;
185 i < bch_opt_synonyms + ARRAY_SIZE(bch_opt_synonyms);
187 if (!strcmp(name, i->s1))
190 return bch2_opt_lookup(name);
193 int bch2_opt_parse(struct bch_fs *c, const struct bch_option *opt,
194 const char *val, u64 *res)
200 ret = kstrtou64(val, 10, res);
208 ret = kstrtou64(val, 10, res);
212 if (*res < opt->min || *res >= opt->max)
215 case BCH_OPT_SECTORS:
216 ret = bch2_strtou64_h(val, res);
225 if (*res < opt->min || *res >= opt->max)
229 ret = match_string(opt->choices, -1, val);
239 return opt->parse(c, val, res);
245 void bch2_opt_to_text(struct printbuf *out, struct bch_fs *c,
246 const struct bch_option *opt, u64 v,
249 if (flags & OPT_SHOW_MOUNT_STYLE) {
250 if (opt->type == BCH_OPT_BOOL) {
257 pr_buf(out, "%s=", opt->attr.name);
263 pr_buf(out, "%lli", v);
265 case BCH_OPT_SECTORS:
269 if (flags & OPT_SHOW_FULL_LIST)
270 bch2_string_opt_to_text(out, opt->choices, v);
272 pr_buf(out, opt->choices[v]);
275 opt->to_text(out, c, v);
282 int bch2_opt_check_may_set(struct bch_fs *c, int id, u64 v)
287 case Opt_compression:
288 case Opt_background_compression:
289 ret = bch2_check_set_has_compressed_data(c, v);
291 case Opt_erasure_code:
293 bch2_check_set_feature(c, BCH_FEATURE_ec);
300 int bch2_opts_check_may_set(struct bch_fs *c)
305 for (i = 0; i < bch2_opts_nr; i++) {
306 ret = bch2_opt_check_may_set(c, i,
307 bch2_opt_get_by_id(&c->opts, i));
315 int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
318 char *opt, *name, *val;
322 while ((opt = strsep(&options, ",")) != NULL) {
323 name = strsep(&opt, "=");
327 id = bch2_mount_opt_lookup(name);
331 ret = bch2_opt_parse(c, &bch2_opt_table[id], val, &v);
335 id = bch2_mount_opt_lookup(name);
339 !strncmp("no", name, 2)) {
340 id = bch2_mount_opt_lookup(name + 2);
347 if (bch2_opt_table[id].type != BCH_OPT_BOOL)
351 if (!(bch2_opt_table[id].mode & OPT_MOUNT))
355 !IS_ENABLED(CONFIG_BCACHEFS_POSIX_ACL))
358 if ((id == Opt_usrquota ||
359 id == Opt_grpquota) &&
360 !IS_ENABLED(CONFIG_BCACHEFS_QUOTA))
363 bch2_opt_set_by_id(opts, id, v);
368 pr_err("Bad mount option %s", name);
371 pr_err("Invalid value %s for mount option %s", val, name);
374 pr_err("Mount option %s requires a value", name);
380 struct bch_io_opts bch2_opts_to_inode_opts(struct bch_opts src)
382 struct bch_io_opts ret = { 0 };
383 #define x(_name, _bits) \
384 if (opt_defined(src, _name)) \
385 opt_set(ret, _name, src._name);
391 struct bch_opts bch2_inode_opts_to_opts(struct bch_io_opts src)
393 struct bch_opts ret = { 0 };
394 #define x(_name, _bits) \
395 if (opt_defined(src, _name)) \
396 opt_set(ret, _name, src._name);
402 void bch2_io_opts_apply(struct bch_io_opts *dst, struct bch_io_opts src)
404 #define x(_name, _bits) \
405 if (opt_defined(src, _name)) \
406 opt_set(*dst, _name, src._name);
411 bool bch2_opt_is_inode_opt(enum bch_opt_id id)
413 static const enum bch_opt_id inode_opt_list[] = {
414 #define x(_name, _bits) Opt_##_name,
420 for (i = 0; i < ARRAY_SIZE(inode_opt_list); i++)
421 if (inode_opt_list[i] == id)