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_types[] = {
39 const char * const bch2_csum_opts[] = {
44 const char * const bch2_compression_types[] = {
45 BCH_COMPRESSION_TYPES()
49 const char * const bch2_compression_opts[] = {
50 BCH_COMPRESSION_OPTS()
54 const char * const bch2_str_hash_types[] = {
59 const char * const bch2_str_hash_opts[] = {
64 const char * const bch2_data_types[] = {
69 const char * const bch2_cache_replacement_policies[] = {
70 BCH_CACHE_REPLACEMENT_POLICIES()
74 const char * const bch2_member_states[] = {
81 const char * const bch2_d_types[BCH_DT_MAX] = {
82 [DT_UNKNOWN] = "unknown",
90 [DT_WHT] = "whiteout",
91 [DT_SUBVOL] = "subvol",
94 void bch2_opts_apply(struct bch_opts *dst, struct bch_opts src)
96 #define x(_name, ...) \
97 if (opt_defined(src, _name)) \
98 opt_set(*dst, _name, src._name);
104 bool bch2_opt_defined_by_id(const struct bch_opts *opts, enum bch_opt_id id)
107 #define x(_name, ...) \
109 return opt_defined(*opts, _name);
117 u64 bch2_opt_get_by_id(const struct bch_opts *opts, enum bch_opt_id id)
120 #define x(_name, ...) \
130 void bch2_opt_set_by_id(struct bch_opts *opts, enum bch_opt_id id, u64 v)
133 #define x(_name, ...) \
135 opt_set(*opts, _name, v); \
145 * Initial options from superblock - here we don't want any options undefined,
146 * any options the superblock doesn't specify are set to 0:
148 struct bch_opts bch2_opts_from_sb(struct bch_sb *sb)
150 struct bch_opts opts = bch2_opts_empty();
152 #define x(_name, _bits, _mode, _type, _sb_opt, ...) \
153 if (_sb_opt != NO_SB_OPT) \
154 opt_set(opts, _name, _sb_opt(sb));
161 const struct bch_option bch2_opt_table[] = {
162 #define OPT_BOOL() .type = BCH_OPT_BOOL
163 #define OPT_UINT(_min, _max) .type = BCH_OPT_UINT, .min = _min, .max = _max
164 #define OPT_SECTORS(_min, _max) .type = BCH_OPT_SECTORS, .min = _min, .max = _max
165 #define OPT_STR(_choices) .type = BCH_OPT_STR, .choices = _choices
166 #define OPT_FN(_fn) .type = BCH_OPT_FN, \
167 .parse = _fn##_parse, \
168 .to_text = _fn##_to_text
170 #define x(_name, _bits, _mode, _type, _sb_opt, _default, _hint, _help) \
174 .mode = (_mode) & OPT_RUNTIME ? 0644 : 0444, \
179 .set_sb = SET_##_sb_opt, \
187 int bch2_opt_lookup(const char *name)
189 const struct bch_option *i;
191 for (i = bch2_opt_table;
192 i < bch2_opt_table + ARRAY_SIZE(bch2_opt_table);
194 if (!strcmp(name, i->attr.name))
195 return i - bch2_opt_table;
204 static const struct synonym bch_opt_synonyms[] = {
205 { "quota", "usrquota" },
208 static int bch2_mount_opt_lookup(const char *name)
210 const struct synonym *i;
212 for (i = bch_opt_synonyms;
213 i < bch_opt_synonyms + ARRAY_SIZE(bch_opt_synonyms);
215 if (!strcmp(name, i->s1))
218 return bch2_opt_lookup(name);
221 int bch2_opt_parse(struct bch_fs *c, const struct bch_option *opt,
222 const char *val, u64 *res)
228 ret = kstrtou64(val, 10, res);
236 ret = kstrtou64(val, 10, res);
240 if (*res < opt->min || *res >= opt->max)
243 case BCH_OPT_SECTORS:
244 ret = bch2_strtou64_h(val, res);
253 if (*res < opt->min || *res >= opt->max)
257 ret = match_string(opt->choices, -1, val);
267 return opt->parse(c, val, res);
273 void bch2_opt_to_text(struct printbuf *out, struct bch_fs *c,
274 const struct bch_option *opt, u64 v,
277 if (flags & OPT_SHOW_MOUNT_STYLE) {
278 if (opt->type == BCH_OPT_BOOL) {
285 pr_buf(out, "%s=", opt->attr.name);
291 pr_buf(out, "%lli", v);
293 case BCH_OPT_SECTORS:
297 if (flags & OPT_SHOW_FULL_LIST)
298 bch2_string_opt_to_text(out, opt->choices, v);
300 pr_buf(out, opt->choices[v]);
303 opt->to_text(out, c, v);
310 int bch2_opt_check_may_set(struct bch_fs *c, int id, u64 v)
315 case Opt_compression:
316 case Opt_background_compression:
317 ret = bch2_check_set_has_compressed_data(c, v);
319 case Opt_erasure_code:
321 bch2_check_set_feature(c, BCH_FEATURE_ec);
328 int bch2_opts_check_may_set(struct bch_fs *c)
333 for (i = 0; i < bch2_opts_nr; i++) {
334 ret = bch2_opt_check_may_set(c, i,
335 bch2_opt_get_by_id(&c->opts, i));
343 int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
346 char *copied_opts, *copied_opts_start;
347 char *opt, *name, *val;
354 copied_opts = kstrdup(options, GFP_KERNEL);
357 copied_opts_start = copied_opts;
359 while ((opt = strsep(&copied_opts, ",")) != NULL) {
360 name = strsep(&opt, "=");
364 id = bch2_mount_opt_lookup(name);
368 ret = bch2_opt_parse(c, &bch2_opt_table[id], val, &v);
372 id = bch2_mount_opt_lookup(name);
376 !strncmp("no", name, 2)) {
377 id = bch2_mount_opt_lookup(name + 2);
384 if (bch2_opt_table[id].type != BCH_OPT_BOOL)
388 if (!(bch2_opt_table[id].mode & OPT_MOUNT))
392 !IS_ENABLED(CONFIG_BCACHEFS_POSIX_ACL))
395 if ((id == Opt_usrquota ||
396 id == Opt_grpquota) &&
397 !IS_ENABLED(CONFIG_BCACHEFS_QUOTA))
400 bch2_opt_set_by_id(opts, id, v);
407 pr_err("Bad mount option %s", name);
411 pr_err("Invalid value %s for mount option %s", val, name);
415 pr_err("Mount option %s requires a value", name);
419 kfree(copied_opts_start);
425 struct bch_io_opts bch2_opts_to_inode_opts(struct bch_opts src)
427 struct bch_io_opts ret = { 0 };
428 #define x(_name, _bits) \
429 if (opt_defined(src, _name)) \
430 opt_set(ret, _name, src._name);
436 struct bch_opts bch2_inode_opts_to_opts(struct bch_io_opts src)
438 struct bch_opts ret = { 0 };
439 #define x(_name, _bits) \
440 if (opt_defined(src, _name)) \
441 opt_set(ret, _name, src._name);
447 void bch2_io_opts_apply(struct bch_io_opts *dst, struct bch_io_opts src)
449 #define x(_name, _bits) \
450 if (opt_defined(src, _name)) \
451 opt_set(*dst, _name, src._name);
456 bool bch2_opt_is_inode_opt(enum bch_opt_id id)
458 static const enum bch_opt_id inode_opt_list[] = {
459 #define x(_name, _bits) Opt_##_name,
465 for (i = 0; i < ARRAY_SIZE(inode_opt_list); i++)
466 if (inode_opt_list[i] == id)