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 const char * const bch2_d_types[DT_MAX] = {
67 [DT_UNKNOWN] = "unknown",
75 [DT_WHT] = "whiteout",
78 void bch2_opts_apply(struct bch_opts *dst, struct bch_opts src)
80 #define x(_name, ...) \
81 if (opt_defined(src, _name)) \
82 opt_set(*dst, _name, src._name);
88 bool bch2_opt_defined_by_id(const struct bch_opts *opts, enum bch_opt_id id)
91 #define x(_name, ...) \
93 return opt_defined(*opts, _name);
101 u64 bch2_opt_get_by_id(const struct bch_opts *opts, enum bch_opt_id id)
104 #define x(_name, ...) \
114 void bch2_opt_set_by_id(struct bch_opts *opts, enum bch_opt_id id, u64 v)
117 #define x(_name, ...) \
119 opt_set(*opts, _name, v); \
129 * Initial options from superblock - here we don't want any options undefined,
130 * any options the superblock doesn't specify are set to 0:
132 struct bch_opts bch2_opts_from_sb(struct bch_sb *sb)
134 struct bch_opts opts = bch2_opts_empty();
136 #define x(_name, _bits, _mode, _type, _sb_opt, ...) \
137 if (_sb_opt != NO_SB_OPT) \
138 opt_set(opts, _name, _sb_opt(sb));
145 const struct bch_option bch2_opt_table[] = {
146 #define OPT_BOOL() .type = BCH_OPT_BOOL
147 #define OPT_UINT(_min, _max) .type = BCH_OPT_UINT, .min = _min, .max = _max
148 #define OPT_SECTORS(_min, _max) .type = BCH_OPT_SECTORS, .min = _min, .max = _max
149 #define OPT_STR(_choices) .type = BCH_OPT_STR, .choices = _choices
150 #define OPT_FN(_fn) .type = BCH_OPT_FN, \
151 .parse = _fn##_parse, \
152 .to_text = _fn##_to_text
154 #define x(_name, _bits, _mode, _type, _sb_opt, _default, _hint, _help) \
158 .mode = (_mode) & OPT_RUNTIME ? 0644 : 0444, \
163 .set_sb = SET_##_sb_opt, \
171 int bch2_opt_lookup(const char *name)
173 const struct bch_option *i;
175 for (i = bch2_opt_table;
176 i < bch2_opt_table + ARRAY_SIZE(bch2_opt_table);
178 if (!strcmp(name, i->attr.name))
179 return i - bch2_opt_table;
188 static const struct synonym bch_opt_synonyms[] = {
189 { "quota", "usrquota" },
192 static int bch2_mount_opt_lookup(const char *name)
194 const struct synonym *i;
196 for (i = bch_opt_synonyms;
197 i < bch_opt_synonyms + ARRAY_SIZE(bch_opt_synonyms);
199 if (!strcmp(name, i->s1))
202 return bch2_opt_lookup(name);
205 int bch2_opt_parse(struct bch_fs *c, const struct bch_option *opt,
206 const char *val, u64 *res)
212 ret = kstrtou64(val, 10, res);
220 ret = kstrtou64(val, 10, res);
224 if (*res < opt->min || *res >= opt->max)
227 case BCH_OPT_SECTORS:
228 ret = bch2_strtou64_h(val, res);
237 if (*res < opt->min || *res >= opt->max)
241 ret = match_string(opt->choices, -1, val);
251 return opt->parse(c, val, res);
257 void bch2_opt_to_text(struct printbuf *out, struct bch_fs *c,
258 const struct bch_option *opt, u64 v,
261 if (flags & OPT_SHOW_MOUNT_STYLE) {
262 if (opt->type == BCH_OPT_BOOL) {
269 pr_buf(out, "%s=", opt->attr.name);
275 pr_buf(out, "%lli", v);
277 case BCH_OPT_SECTORS:
281 if (flags & OPT_SHOW_FULL_LIST)
282 bch2_string_opt_to_text(out, opt->choices, v);
284 pr_buf(out, opt->choices[v]);
287 opt->to_text(out, c, v);
294 int bch2_opt_check_may_set(struct bch_fs *c, int id, u64 v)
299 case Opt_compression:
300 case Opt_background_compression:
301 ret = bch2_check_set_has_compressed_data(c, v);
303 case Opt_erasure_code:
305 bch2_check_set_feature(c, BCH_FEATURE_ec);
312 int bch2_opts_check_may_set(struct bch_fs *c)
317 for (i = 0; i < bch2_opts_nr; i++) {
318 ret = bch2_opt_check_may_set(c, i,
319 bch2_opt_get_by_id(&c->opts, i));
327 int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
330 char *copied_opts, *copied_opts_start;
331 char *opt, *name, *val;
338 copied_opts = kstrdup(options, GFP_KERNEL);
341 copied_opts_start = copied_opts;
343 while ((opt = strsep(&copied_opts, ",")) != NULL) {
344 name = strsep(&opt, "=");
348 id = bch2_mount_opt_lookup(name);
352 ret = bch2_opt_parse(c, &bch2_opt_table[id], val, &v);
356 id = bch2_mount_opt_lookup(name);
360 !strncmp("no", name, 2)) {
361 id = bch2_mount_opt_lookup(name + 2);
368 if (bch2_opt_table[id].type != BCH_OPT_BOOL)
372 if (!(bch2_opt_table[id].mode & OPT_MOUNT))
376 !IS_ENABLED(CONFIG_BCACHEFS_POSIX_ACL))
379 if ((id == Opt_usrquota ||
380 id == Opt_grpquota) &&
381 !IS_ENABLED(CONFIG_BCACHEFS_QUOTA))
384 bch2_opt_set_by_id(opts, id, v);
391 pr_err("Bad mount option %s", name);
395 pr_err("Invalid value %s for mount option %s", val, name);
399 pr_err("Mount option %s requires a value", name);
403 kfree(copied_opts_start);
409 struct bch_io_opts bch2_opts_to_inode_opts(struct bch_opts src)
411 struct bch_io_opts ret = { 0 };
412 #define x(_name, _bits) \
413 if (opt_defined(src, _name)) \
414 opt_set(ret, _name, src._name);
420 struct bch_opts bch2_inode_opts_to_opts(struct bch_io_opts src)
422 struct bch_opts ret = { 0 };
423 #define x(_name, _bits) \
424 if (opt_defined(src, _name)) \
425 opt_set(ret, _name, src._name);
431 void bch2_io_opts_apply(struct bch_io_opts *dst, struct bch_io_opts src)
433 #define x(_name, _bits) \
434 if (opt_defined(src, _name)) \
435 opt_set(*dst, _name, src._name);
440 bool bch2_opt_is_inode_opt(enum bch_opt_id id)
442 static const enum bch_opt_id inode_opt_list[] = {
443 #define x(_name, _bits) Opt_##_name,
449 for (i = 0; i < ARRAY_SIZE(inode_opt_list); i++)
450 if (inode_opt_list[i] == id)