1// SPDX-License-Identifier: GPL-2.0
2
3#include <linux/kernel.h>
4
5#include "bcachefs.h"
6#include "compress.h"
7#include "disk_groups.h"
8#include "error.h"
9#include "opts.h"
10#include "recovery_passes.h"
11#include "super-io.h"
12#include "util.h"
13
14#define x(t, n, ...) [n] = #t,
15
16const char * const bch2_error_actions[] = {
17	BCH_ERROR_ACTIONS()
18	NULL
19};
20
21const char * const bch2_fsck_fix_opts[] = {
22	BCH_FIX_ERRORS_OPTS()
23	NULL
24};
25
26const char * const bch2_version_upgrade_opts[] = {
27	BCH_VERSION_UPGRADE_OPTS()
28	NULL
29};
30
31const char * const bch2_sb_features[] = {
32	BCH_SB_FEATURES()
33	NULL
34};
35
36const char * const bch2_sb_compat[] = {
37	BCH_SB_COMPAT()
38	NULL
39};
40
41const char * const __bch2_btree_ids[] = {
42	BCH_BTREE_IDS()
43	NULL
44};
45
46static const char * const __bch2_csum_types[] = {
47	BCH_CSUM_TYPES()
48	NULL
49};
50
51const char * const bch2_csum_opts[] = {
52	BCH_CSUM_OPTS()
53	NULL
54};
55
56static const char * const __bch2_compression_types[] = {
57	BCH_COMPRESSION_TYPES()
58	NULL
59};
60
61const char * const bch2_compression_opts[] = {
62	BCH_COMPRESSION_OPTS()
63	NULL
64};
65
66const char * const bch2_str_hash_types[] = {
67	BCH_STR_HASH_TYPES()
68	NULL
69};
70
71const char * const bch2_str_hash_opts[] = {
72	BCH_STR_HASH_OPTS()
73	NULL
74};
75
76const char * const __bch2_data_types[] = {
77	BCH_DATA_TYPES()
78	NULL
79};
80
81const char * const bch2_member_states[] = {
82	BCH_MEMBER_STATES()
83	NULL
84};
85
86static const char * const __bch2_jset_entry_types[] = {
87	BCH_JSET_ENTRY_TYPES()
88	NULL
89};
90
91static const char * const __bch2_fs_usage_types[] = {
92	BCH_FS_USAGE_TYPES()
93	NULL
94};
95
96#undef x
97
98static void prt_str_opt_boundscheck(struct printbuf *out, const char * const opts[],
99				    unsigned nr, const char *type, unsigned idx)
100{
101	if (idx < nr)
102		prt_str(out, opts[idx]);
103	else
104		prt_printf(out, "(unknown %s %u)", type, idx);
105}
106
107#define PRT_STR_OPT_BOUNDSCHECKED(name, type)					\
108void bch2_prt_##name(struct printbuf *out, type t)				\
109{										\
110	prt_str_opt_boundscheck(out, __bch2_##name##s, ARRAY_SIZE(__bch2_##name##s) - 1, #name, t);\
111}
112
113PRT_STR_OPT_BOUNDSCHECKED(jset_entry_type,	enum bch_jset_entry_type);
114PRT_STR_OPT_BOUNDSCHECKED(fs_usage_type,	enum bch_fs_usage_type);
115PRT_STR_OPT_BOUNDSCHECKED(data_type,		enum bch_data_type);
116PRT_STR_OPT_BOUNDSCHECKED(csum_type,		enum bch_csum_type);
117PRT_STR_OPT_BOUNDSCHECKED(compression_type,	enum bch_compression_type);
118
119static int bch2_opt_fix_errors_parse(struct bch_fs *c, const char *val, u64 *res,
120				     struct printbuf *err)
121{
122	if (!val) {
123		*res = FSCK_FIX_yes;
124	} else {
125		int ret = match_string(bch2_fsck_fix_opts, -1, val);
126
127		if (ret < 0 && err)
128			prt_str(err, "fix_errors: invalid selection");
129		if (ret < 0)
130			return ret;
131		*res = ret;
132	}
133
134	return 0;
135}
136
137static void bch2_opt_fix_errors_to_text(struct printbuf *out,
138					struct bch_fs *c,
139					struct bch_sb *sb,
140					u64 v)
141{
142	prt_str(out, bch2_fsck_fix_opts[v]);
143}
144
145#define bch2_opt_fix_errors (struct bch_opt_fn) {	\
146	.parse = bch2_opt_fix_errors_parse,		\
147	.to_text = bch2_opt_fix_errors_to_text,		\
148}
149
150const char * const bch2_d_types[BCH_DT_MAX] = {
151	[DT_UNKNOWN]	= "unknown",
152	[DT_FIFO]	= "fifo",
153	[DT_CHR]	= "chr",
154	[DT_DIR]	= "dir",
155	[DT_BLK]	= "blk",
156	[DT_REG]	= "reg",
157	[DT_LNK]	= "lnk",
158	[DT_SOCK]	= "sock",
159	[DT_WHT]	= "whiteout",
160	[DT_SUBVOL]	= "subvol",
161};
162
163u64 BCH2_NO_SB_OPT(const struct bch_sb *sb)
164{
165	BUG();
166}
167
168void SET_BCH2_NO_SB_OPT(struct bch_sb *sb, u64 v)
169{
170	BUG();
171}
172
173void bch2_opts_apply(struct bch_opts *dst, struct bch_opts src)
174{
175#define x(_name, ...)						\
176	if (opt_defined(src, _name))					\
177		opt_set(*dst, _name, src._name);
178
179	BCH_OPTS()
180#undef x
181}
182
183bool bch2_opt_defined_by_id(const struct bch_opts *opts, enum bch_opt_id id)
184{
185	switch (id) {
186#define x(_name, ...)						\
187	case Opt_##_name:						\
188		return opt_defined(*opts, _name);
189	BCH_OPTS()
190#undef x
191	default:
192		BUG();
193	}
194}
195
196u64 bch2_opt_get_by_id(const struct bch_opts *opts, enum bch_opt_id id)
197{
198	switch (id) {
199#define x(_name, ...)						\
200	case Opt_##_name:						\
201		return opts->_name;
202	BCH_OPTS()
203#undef x
204	default:
205		BUG();
206	}
207}
208
209void bch2_opt_set_by_id(struct bch_opts *opts, enum bch_opt_id id, u64 v)
210{
211	switch (id) {
212#define x(_name, ...)						\
213	case Opt_##_name:						\
214		opt_set(*opts, _name, v);				\
215		break;
216	BCH_OPTS()
217#undef x
218	default:
219		BUG();
220	}
221}
222
223const struct bch_option bch2_opt_table[] = {
224#define OPT_BOOL()		.type = BCH_OPT_BOOL, .min = 0, .max = 2
225#define OPT_UINT(_min, _max)	.type = BCH_OPT_UINT,			\
226				.min = _min, .max = _max
227#define OPT_STR(_choices)	.type = BCH_OPT_STR,			\
228				.min = 0, .max = ARRAY_SIZE(_choices),	\
229				.choices = _choices
230#define OPT_STR_NOLIMIT(_choices)	.type = BCH_OPT_STR,		\
231				.min = 0, .max = U64_MAX,		\
232				.choices = _choices
233#define OPT_FN(_fn)		.type = BCH_OPT_FN, .fn	= _fn
234
235#define x(_name, _bits, _flags, _type, _sb_opt, _default, _hint, _help)	\
236	[Opt_##_name] = {						\
237		.attr	= {						\
238			.name	= #_name,				\
239			.mode = (_flags) & OPT_RUNTIME ? 0644 : 0444,	\
240		},							\
241		.flags	= _flags,					\
242		.hint	= _hint,					\
243		.help	= _help,					\
244		.get_sb = _sb_opt,					\
245		.set_sb	= SET_##_sb_opt,				\
246		_type							\
247	},
248
249	BCH_OPTS()
250#undef x
251};
252
253int bch2_opt_lookup(const char *name)
254{
255	const struct bch_option *i;
256
257	for (i = bch2_opt_table;
258	     i < bch2_opt_table + ARRAY_SIZE(bch2_opt_table);
259	     i++)
260		if (!strcmp(name, i->attr.name))
261			return i - bch2_opt_table;
262
263	return -1;
264}
265
266struct synonym {
267	const char	*s1, *s2;
268};
269
270static const struct synonym bch_opt_synonyms[] = {
271	{ "quota",	"usrquota" },
272};
273
274static int bch2_mount_opt_lookup(const char *name)
275{
276	const struct synonym *i;
277
278	for (i = bch_opt_synonyms;
279	     i < bch_opt_synonyms + ARRAY_SIZE(bch_opt_synonyms);
280	     i++)
281		if (!strcmp(name, i->s1))
282			name = i->s2;
283
284	return bch2_opt_lookup(name);
285}
286
287int bch2_opt_validate(const struct bch_option *opt, u64 v, struct printbuf *err)
288{
289	if (v < opt->min) {
290		if (err)
291			prt_printf(err, "%s: too small (min %llu)",
292			       opt->attr.name, opt->min);
293		return -BCH_ERR_ERANGE_option_too_small;
294	}
295
296	if (opt->max && v >= opt->max) {
297		if (err)
298			prt_printf(err, "%s: too big (max %llu)",
299			       opt->attr.name, opt->max);
300		return -BCH_ERR_ERANGE_option_too_big;
301	}
302
303	if ((opt->flags & OPT_SB_FIELD_SECTORS) && (v & 511)) {
304		if (err)
305			prt_printf(err, "%s: not a multiple of 512",
306			       opt->attr.name);
307		return -BCH_ERR_opt_parse_error;
308	}
309
310	if ((opt->flags & OPT_MUST_BE_POW_2) && !is_power_of_2(v)) {
311		if (err)
312			prt_printf(err, "%s: must be a power of two",
313			       opt->attr.name);
314		return -BCH_ERR_opt_parse_error;
315	}
316
317	if (opt->fn.validate)
318		return opt->fn.validate(v, err);
319
320	return 0;
321}
322
323int bch2_opt_parse(struct bch_fs *c,
324		   const struct bch_option *opt,
325		   const char *val, u64 *res,
326		   struct printbuf *err)
327{
328	ssize_t ret;
329
330	switch (opt->type) {
331	case BCH_OPT_BOOL:
332		if (val) {
333			ret = kstrtou64(val, 10, res);
334		} else {
335			ret = 0;
336			*res = 1;
337		}
338
339		if (ret < 0 || (*res != 0 && *res != 1)) {
340			if (err)
341				prt_printf(err, "%s: must be bool", opt->attr.name);
342			return ret < 0 ? ret : -BCH_ERR_option_not_bool;
343		}
344		break;
345	case BCH_OPT_UINT:
346		if (!val) {
347			prt_printf(err, "%s: required value",
348				   opt->attr.name);
349			return -EINVAL;
350		}
351
352		ret = opt->flags & OPT_HUMAN_READABLE
353			? bch2_strtou64_h(val, res)
354			: kstrtou64(val, 10, res);
355		if (ret < 0) {
356			if (err)
357				prt_printf(err, "%s: must be a number",
358					   opt->attr.name);
359			return ret;
360		}
361		break;
362	case BCH_OPT_STR:
363		if (!val) {
364			prt_printf(err, "%s: required value",
365				   opt->attr.name);
366			return -EINVAL;
367		}
368
369		ret = match_string(opt->choices, -1, val);
370		if (ret < 0) {
371			if (err)
372				prt_printf(err, "%s: invalid selection",
373					   opt->attr.name);
374			return ret;
375		}
376
377		*res = ret;
378		break;
379	case BCH_OPT_FN:
380		ret = opt->fn.parse(c, val, res, err);
381		if (ret < 0) {
382			if (err)
383				prt_printf(err, "%s: parse error",
384					   opt->attr.name);
385			return ret;
386		}
387	}
388
389	return bch2_opt_validate(opt, *res, err);
390}
391
392void bch2_opt_to_text(struct printbuf *out,
393		      struct bch_fs *c, struct bch_sb *sb,
394		      const struct bch_option *opt, u64 v,
395		      unsigned flags)
396{
397	if (flags & OPT_SHOW_MOUNT_STYLE) {
398		if (opt->type == BCH_OPT_BOOL) {
399			prt_printf(out, "%s%s",
400			       v ? "" : "no",
401			       opt->attr.name);
402			return;
403		}
404
405		prt_printf(out, "%s=", opt->attr.name);
406	}
407
408	switch (opt->type) {
409	case BCH_OPT_BOOL:
410	case BCH_OPT_UINT:
411		if (opt->flags & OPT_HUMAN_READABLE)
412			prt_human_readable_u64(out, v);
413		else
414			prt_printf(out, "%lli", v);
415		break;
416	case BCH_OPT_STR:
417		if (flags & OPT_SHOW_FULL_LIST)
418			prt_string_option(out, opt->choices, v);
419		else
420			prt_str(out, opt->choices[v]);
421		break;
422	case BCH_OPT_FN:
423		opt->fn.to_text(out, c, sb, v);
424		break;
425	default:
426		BUG();
427	}
428}
429
430int bch2_opt_check_may_set(struct bch_fs *c, int id, u64 v)
431{
432	int ret = 0;
433
434	switch (id) {
435	case Opt_compression:
436	case Opt_background_compression:
437		ret = bch2_check_set_has_compressed_data(c, v);
438		break;
439	case Opt_erasure_code:
440		if (v)
441			bch2_check_set_feature(c, BCH_FEATURE_ec);
442		break;
443	}
444
445	return ret;
446}
447
448int bch2_opts_check_may_set(struct bch_fs *c)
449{
450	unsigned i;
451	int ret;
452
453	for (i = 0; i < bch2_opts_nr; i++) {
454		ret = bch2_opt_check_may_set(c, i,
455				bch2_opt_get_by_id(&c->opts, i));
456		if (ret)
457			return ret;
458	}
459
460	return 0;
461}
462
463int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
464			  char *options)
465{
466	char *copied_opts, *copied_opts_start;
467	char *opt, *name, *val;
468	int ret, id;
469	struct printbuf err = PRINTBUF;
470	u64 v;
471
472	if (!options)
473		return 0;
474
475	/*
476	 * sys_fsconfig() is now occasionally providing us with option lists
477	 * starting with a comma - weird.
478	 */
479	if (*options == ',')
480		options++;
481
482	copied_opts = kstrdup(options, GFP_KERNEL);
483	if (!copied_opts)
484		return -ENOMEM;
485	copied_opts_start = copied_opts;
486
487	while ((opt = strsep(&copied_opts, ",")) != NULL) {
488		name	= strsep(&opt, "=");
489		val	= opt;
490
491		id = bch2_mount_opt_lookup(name);
492
493		/* Check for the form "noopt", negation of a boolean opt: */
494		if (id < 0 &&
495		    !val &&
496		    !strncmp("no", name, 2)) {
497			id = bch2_mount_opt_lookup(name + 2);
498			val = "0";
499		}
500
501		/* Unknown options are ignored: */
502		if (id < 0)
503			continue;
504
505		if (!(bch2_opt_table[id].flags & OPT_MOUNT))
506			goto bad_opt;
507
508		if (id == Opt_acl &&
509		    !IS_ENABLED(CONFIG_BCACHEFS_POSIX_ACL))
510			goto bad_opt;
511
512		if ((id == Opt_usrquota ||
513		     id == Opt_grpquota) &&
514		    !IS_ENABLED(CONFIG_BCACHEFS_QUOTA))
515			goto bad_opt;
516
517		ret = bch2_opt_parse(c, &bch2_opt_table[id], val, &v, &err);
518		if (ret < 0)
519			goto bad_val;
520
521		bch2_opt_set_by_id(opts, id, v);
522	}
523
524	ret = 0;
525	goto out;
526
527bad_opt:
528	pr_err("Bad mount option %s", name);
529	ret = -BCH_ERR_option_name;
530	goto out;
531bad_val:
532	pr_err("Invalid mount option %s", err.buf);
533	ret = -BCH_ERR_option_value;
534	goto out;
535out:
536	kfree(copied_opts_start);
537	printbuf_exit(&err);
538	return ret;
539}
540
541u64 bch2_opt_from_sb(struct bch_sb *sb, enum bch_opt_id id)
542{
543	const struct bch_option *opt = bch2_opt_table + id;
544	u64 v;
545
546	v = opt->get_sb(sb);
547
548	if (opt->flags & OPT_SB_FIELD_ILOG2)
549		v = 1ULL << v;
550
551	if (opt->flags & OPT_SB_FIELD_SECTORS)
552		v <<= 9;
553
554	return v;
555}
556
557/*
558 * Initial options from superblock - here we don't want any options undefined,
559 * any options the superblock doesn't specify are set to 0:
560 */
561int bch2_opts_from_sb(struct bch_opts *opts, struct bch_sb *sb)
562{
563	unsigned id;
564
565	for (id = 0; id < bch2_opts_nr; id++) {
566		const struct bch_option *opt = bch2_opt_table + id;
567
568		if (opt->get_sb == BCH2_NO_SB_OPT)
569			continue;
570
571		bch2_opt_set_by_id(opts, id, bch2_opt_from_sb(sb, id));
572	}
573
574	return 0;
575}
576
577void __bch2_opt_set_sb(struct bch_sb *sb, const struct bch_option *opt, u64 v)
578{
579	if (opt->set_sb == SET_BCH2_NO_SB_OPT)
580		return;
581
582	if (opt->flags & OPT_SB_FIELD_SECTORS)
583		v >>= 9;
584
585	if (opt->flags & OPT_SB_FIELD_ILOG2)
586		v = ilog2(v);
587
588	opt->set_sb(sb, v);
589}
590
591void bch2_opt_set_sb(struct bch_fs *c, const struct bch_option *opt, u64 v)
592{
593	if (opt->set_sb == SET_BCH2_NO_SB_OPT)
594		return;
595
596	mutex_lock(&c->sb_lock);
597	__bch2_opt_set_sb(c->disk_sb.sb, opt, v);
598	bch2_write_super(c);
599	mutex_unlock(&c->sb_lock);
600}
601
602/* io opts: */
603
604struct bch_io_opts bch2_opts_to_inode_opts(struct bch_opts src)
605{
606	return (struct bch_io_opts) {
607#define x(_name, _bits)	._name = src._name,
608	BCH_INODE_OPTS()
609#undef x
610	};
611}
612
613bool bch2_opt_is_inode_opt(enum bch_opt_id id)
614{
615	static const enum bch_opt_id inode_opt_list[] = {
616#define x(_name, _bits)	Opt_##_name,
617	BCH_INODE_OPTS()
618#undef x
619	};
620	unsigned i;
621
622	for (i = 0; i < ARRAY_SIZE(inode_opt_list); i++)
623		if (inode_opt_list[i] == id)
624			return true;
625
626	return false;
627}
628