| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | // SPDX-License-Identifier: GPL-2.0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/kernel.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "bcachefs.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-12 18:30:55 -05:00
										 |  |  | #include "compress.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | #include "disk_groups.h"
 | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | #include "error.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | #include "opts.h"
 | 
					
						
							|  |  |  | #include "super-io.h"
 | 
					
						
							|  |  |  | #include "util.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-21 05:38:45 -04:00
										 |  |  | #define x(t, n, ...) [n] = #t,
 | 
					
						
							| 
									
										
										
										
											2022-03-20 23:34:11 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-25 00:46:28 -04:00
										 |  |  | const char * const bch2_iops_measurements[] = { | 
					
						
							|  |  |  | 	BCH_IOPS_MEASUREMENTS() | 
					
						
							|  |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | const char * const bch2_error_actions[] = { | 
					
						
							| 
									
										
										
										
											2021-02-20 19:47:58 -05:00
										 |  |  | 	BCH_ERROR_ACTIONS() | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | const char * const bch2_fsck_fix_opts[] = { | 
					
						
							|  |  |  | 	BCH_FIX_ERRORS_OPTS() | 
					
						
							|  |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-27 23:34:02 -04:00
										 |  |  | const char * const bch2_version_upgrade_opts[] = { | 
					
						
							|  |  |  | 	BCH_VERSION_UPGRADE_OPTS() | 
					
						
							|  |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-28 20:17:06 -05:00
										 |  |  | const char * const bch2_sb_features[] = { | 
					
						
							|  |  |  | 	BCH_SB_FEATURES() | 
					
						
							|  |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-04 21:57:35 -04:00
										 |  |  | const char * const bch2_sb_compat[] = { | 
					
						
							|  |  |  | 	BCH_SB_COMPAT() | 
					
						
							|  |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-19 22:49:08 -04:00
										 |  |  | const char * const __bch2_btree_ids[] = { | 
					
						
							| 
									
										
										
										
											2021-02-20 19:27:37 -05:00
										 |  |  | 	BCH_BTREE_IDS() | 
					
						
							|  |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 12:11:33 -05:00
										 |  |  | const char * const bch2_csum_types[] = { | 
					
						
							|  |  |  | 	BCH_CSUM_TYPES() | 
					
						
							|  |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-28 20:17:06 -05:00
										 |  |  | const char * const bch2_csum_opts[] = { | 
					
						
							| 
									
										
										
										
											2021-02-20 19:47:58 -05:00
										 |  |  | 	BCH_CSUM_OPTS() | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 12:11:33 -05:00
										 |  |  | const char * const bch2_compression_types[] = { | 
					
						
							|  |  |  | 	BCH_COMPRESSION_TYPES() | 
					
						
							|  |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-28 20:17:06 -05:00
										 |  |  | const char * const bch2_compression_opts[] = { | 
					
						
							|  |  |  | 	BCH_COMPRESSION_OPTS() | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char * const bch2_str_hash_types[] = { | 
					
						
							| 
									
										
										
										
											2021-11-11 12:11:33 -05:00
										 |  |  | 	BCH_STR_HASH_TYPES() | 
					
						
							|  |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char * const bch2_str_hash_opts[] = { | 
					
						
							| 
									
										
										
										
											2021-02-20 19:47:58 -05:00
										 |  |  | 	BCH_STR_HASH_OPTS() | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char * const bch2_data_types[] = { | 
					
						
							| 
									
										
										
										
											2020-07-09 18:28:11 -04:00
										 |  |  | 	BCH_DATA_TYPES() | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-20 19:47:58 -05:00
										 |  |  | const char * const bch2_member_states[] = { | 
					
						
							|  |  |  | 	BCH_MEMBER_STATES() | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 17:06:29 -05:00
										 |  |  | const char * const bch2_jset_entry_types[] = { | 
					
						
							|  |  |  | 	BCH_JSET_ENTRY_TYPES() | 
					
						
							|  |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char * const bch2_fs_usage_types[] = { | 
					
						
							|  |  |  | 	BCH_FS_USAGE_TYPES() | 
					
						
							|  |  |  | 	NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-20 19:47:58 -05:00
										 |  |  | #undef x
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | static int bch2_opt_fix_errors_parse(struct bch_fs *c, const char *val, u64 *res, | 
					
						
							|  |  |  | 				     struct printbuf *err) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!val) { | 
					
						
							|  |  |  | 		*res = FSCK_FIX_yes; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		int ret = match_string(bch2_fsck_fix_opts, -1, val); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (ret < 0 && err) | 
					
						
							|  |  |  | 			prt_str(err, "fix_errors: invalid selection"); | 
					
						
							|  |  |  | 		if (ret < 0) | 
					
						
							|  |  |  | 			return ret; | 
					
						
							|  |  |  | 		*res = ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void bch2_opt_fix_errors_to_text(struct printbuf *out, | 
					
						
							|  |  |  | 					struct bch_fs *c, | 
					
						
							|  |  |  | 					struct bch_sb *sb, | 
					
						
							|  |  |  | 					u64 v) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	prt_str(out, bch2_fsck_fix_opts[v]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-01 20:06:45 -04:00
										 |  |  | #define bch2_opt_fix_errors (struct bch_opt_fn) {	\
 | 
					
						
							|  |  |  | 	.parse = bch2_opt_fix_errors_parse,		\ | 
					
						
							|  |  |  | 	.to_text = bch2_opt_fix_errors_to_text,		\ | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-16 00:42:25 -04:00
										 |  |  | const char * const bch2_d_types[BCH_DT_MAX] = { | 
					
						
							| 
									
										
										
										
											2021-07-05 22:18:07 -04:00
										 |  |  | 	[DT_UNKNOWN]	= "unknown", | 
					
						
							|  |  |  | 	[DT_FIFO]	= "fifo", | 
					
						
							|  |  |  | 	[DT_CHR]	= "chr", | 
					
						
							|  |  |  | 	[DT_DIR]	= "dir", | 
					
						
							|  |  |  | 	[DT_BLK]	= "blk", | 
					
						
							|  |  |  | 	[DT_REG]	= "reg", | 
					
						
							|  |  |  | 	[DT_LNK]	= "lnk", | 
					
						
							|  |  |  | 	[DT_SOCK]	= "sock", | 
					
						
							|  |  |  | 	[DT_WHT]	= "whiteout", | 
					
						
							| 
									
										
										
										
											2021-03-16 00:42:25 -04:00
										 |  |  | 	[DT_SUBVOL]	= "subvol", | 
					
						
							| 
									
										
										
										
											2021-07-05 22:18:07 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-05 12:01:16 -05:00
										 |  |  | u64 BCH2_NO_SB_OPT(const struct bch_sb *sb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BUG(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SET_BCH2_NO_SB_OPT(struct bch_sb *sb, u64 v) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BUG(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | void bch2_opts_apply(struct bch_opts *dst, struct bch_opts src) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-19 12:58:56 -05:00
										 |  |  | #define x(_name, ...)						\
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	if (opt_defined(src, _name))					\ | 
					
						
							|  |  |  | 		opt_set(*dst, _name, src._name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BCH_OPTS() | 
					
						
							| 
									
										
										
										
											2018-12-19 12:58:56 -05:00
										 |  |  | #undef x
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool bch2_opt_defined_by_id(const struct bch_opts *opts, enum bch_opt_id id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (id) { | 
					
						
							| 
									
										
										
										
											2018-12-19 12:58:56 -05:00
										 |  |  | #define x(_name, ...)						\
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	case Opt_##_name:						\ | 
					
						
							|  |  |  | 		return opt_defined(*opts, _name); | 
					
						
							|  |  |  | 	BCH_OPTS() | 
					
						
							| 
									
										
										
										
											2018-12-19 12:58:56 -05:00
										 |  |  | #undef x
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | u64 bch2_opt_get_by_id(const struct bch_opts *opts, enum bch_opt_id id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (id) { | 
					
						
							| 
									
										
										
										
											2018-12-19 12:58:56 -05:00
										 |  |  | #define x(_name, ...)						\
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	case Opt_##_name:						\ | 
					
						
							|  |  |  | 		return opts->_name; | 
					
						
							|  |  |  | 	BCH_OPTS() | 
					
						
							| 
									
										
										
										
											2018-12-19 12:58:56 -05:00
										 |  |  | #undef x
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void bch2_opt_set_by_id(struct bch_opts *opts, enum bch_opt_id id, u64 v) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (id) { | 
					
						
							| 
									
										
										
										
											2018-12-19 12:58:56 -05:00
										 |  |  | #define x(_name, ...)						\
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	case Opt_##_name:						\ | 
					
						
							|  |  |  | 		opt_set(*opts, _name, v);				\ | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	BCH_OPTS() | 
					
						
							| 
									
										
										
										
											2018-12-19 12:58:56 -05:00
										 |  |  | #undef x
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const struct bch_option bch2_opt_table[] = { | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | #define OPT_BOOL()		.type = BCH_OPT_BOOL, .min = 0, .max = 2
 | 
					
						
							|  |  |  | #define OPT_UINT(_min, _max)	.type = BCH_OPT_UINT,			\
 | 
					
						
							|  |  |  | 				.min = _min, .max = _max | 
					
						
							|  |  |  | #define OPT_STR(_choices)	.type = BCH_OPT_STR,			\
 | 
					
						
							| 
									
										
										
										
											2023-07-12 21:48:32 -04:00
										 |  |  | 				.min = 0, .max = ARRAY_SIZE(_choices),	\ | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 				.choices = _choices | 
					
						
							| 
									
										
										
										
											2023-07-12 21:48:32 -04:00
										 |  |  | #define OPT_FN(_fn)		.type = BCH_OPT_FN, .fn	= _fn
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | #define x(_name, _bits, _flags, _type, _sb_opt, _default, _hint, _help)	\
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	[Opt_##_name] = {						\ | 
					
						
							|  |  |  | 		.attr	= {						\ | 
					
						
							|  |  |  | 			.name	= #_name,				\ | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 			.mode = (_flags) & OPT_RUNTIME ? 0644 : 0444,	\ | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 		},							\ | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		.flags	= _flags,					\ | 
					
						
							| 
									
										
										
										
											2018-12-19 12:58:56 -05:00
										 |  |  | 		.hint	= _hint,					\ | 
					
						
							|  |  |  | 		.help	= _help,					\ | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		.get_sb = _sb_opt,					\ | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 		.set_sb	= SET_##_sb_opt,				\ | 
					
						
							|  |  |  | 		_type							\ | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BCH_OPTS() | 
					
						
							| 
									
										
										
										
											2018-12-19 12:58:56 -05:00
										 |  |  | #undef x
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int bch2_opt_lookup(const char *name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const struct bch_option *i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = bch2_opt_table; | 
					
						
							|  |  |  | 	     i < bch2_opt_table + ARRAY_SIZE(bch2_opt_table); | 
					
						
							|  |  |  | 	     i++) | 
					
						
							|  |  |  | 		if (!strcmp(name, i->attr.name)) | 
					
						
							|  |  |  | 			return i - bch2_opt_table; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct synonym { | 
					
						
							|  |  |  | 	const char	*s1, *s2; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct synonym bch_opt_synonyms[] = { | 
					
						
							|  |  |  | 	{ "quota",	"usrquota" }, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int bch2_mount_opt_lookup(const char *name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const struct synonym *i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = bch_opt_synonyms; | 
					
						
							|  |  |  | 	     i < bch_opt_synonyms + ARRAY_SIZE(bch_opt_synonyms); | 
					
						
							|  |  |  | 	     i++) | 
					
						
							|  |  |  | 		if (!strcmp(name, i->s1)) | 
					
						
							|  |  |  | 			name = i->s2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return bch2_opt_lookup(name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | int bch2_opt_validate(const struct bch_option *opt, u64 v, struct printbuf *err) | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (v < opt->min) { | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 		if (err) | 
					
						
							| 
									
										
										
										
											2023-02-03 21:01:40 -05:00
										 |  |  | 			prt_printf(err, "%s: too small (min %llu)", | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 			       opt->attr.name, opt->min); | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		return -ERANGE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (opt->max && v >= opt->max) { | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 		if (err) | 
					
						
							| 
									
										
										
										
											2023-02-03 21:01:40 -05:00
										 |  |  | 			prt_printf(err, "%s: too big (max %llu)", | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 			       opt->attr.name, opt->max); | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		return -ERANGE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((opt->flags & OPT_SB_FIELD_SECTORS) && (v & 511)) { | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 		if (err) | 
					
						
							| 
									
										
										
										
											2023-02-03 21:01:40 -05:00
										 |  |  | 			prt_printf(err, "%s: not a multiple of 512", | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 			       opt->attr.name); | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((opt->flags & OPT_MUST_BE_POW_2) && !is_power_of_2(v)) { | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 		if (err) | 
					
						
							| 
									
										
										
										
											2023-02-03 21:01:40 -05:00
										 |  |  | 			prt_printf(err, "%s: must be a power of two", | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 			       opt->attr.name); | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | int bch2_opt_parse(struct bch_fs *c, | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		   const struct bch_option *opt, | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 		   const char *val, u64 *res, | 
					
						
							|  |  |  | 		   struct printbuf *err) | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | { | 
					
						
							|  |  |  | 	ssize_t ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (opt->type) { | 
					
						
							|  |  |  | 	case BCH_OPT_BOOL: | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | 		if (val) { | 
					
						
							|  |  |  | 			ret = kstrtou64(val, 10, res); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			ret = 0; | 
					
						
							|  |  |  | 			*res = 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-04 14:49:02 -04:00
										 |  |  | 		if (ret < 0 || (*res != 0 && *res != 1)) { | 
					
						
							|  |  |  | 			if (err) | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | 				prt_printf(err, "%s: must be bool", opt->attr.name); | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 			return ret; | 
					
						
							| 
									
										
										
										
											2022-06-04 14:49:02 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case BCH_OPT_UINT: | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | 		if (!val) { | 
					
						
							|  |  |  | 			prt_printf(err, "%s: required value", | 
					
						
							|  |  |  | 				   opt->attr.name); | 
					
						
							|  |  |  | 			return -EINVAL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		ret = opt->flags & OPT_HUMAN_READABLE | 
					
						
							|  |  |  | 			? bch2_strtou64_h(val, res) | 
					
						
							|  |  |  | 			: kstrtou64(val, 10, res); | 
					
						
							| 
									
										
										
										
											2022-06-04 14:49:02 -04:00
										 |  |  | 		if (ret < 0) { | 
					
						
							|  |  |  | 			if (err) | 
					
						
							| 
									
										
										
										
											2023-02-03 21:01:40 -05:00
										 |  |  | 				prt_printf(err, "%s: must be a number", | 
					
						
							|  |  |  | 					   opt->attr.name); | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 			return ret; | 
					
						
							| 
									
										
										
										
											2022-06-04 14:49:02 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case BCH_OPT_STR: | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | 		if (!val) { | 
					
						
							|  |  |  | 			prt_printf(err, "%s: required value", | 
					
						
							|  |  |  | 				   opt->attr.name); | 
					
						
							|  |  |  | 			return -EINVAL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 		ret = match_string(opt->choices, -1, val); | 
					
						
							| 
									
										
										
										
											2022-06-04 14:49:02 -04:00
										 |  |  | 		if (ret < 0) { | 
					
						
							|  |  |  | 			if (err) | 
					
						
							| 
									
										
										
										
											2023-02-03 21:01:40 -05:00
										 |  |  | 				prt_printf(err, "%s: invalid selection", | 
					
						
							|  |  |  | 					   opt->attr.name); | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 			return ret; | 
					
						
							| 
									
										
										
										
											2022-06-04 14:49:02 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		*res = ret; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case BCH_OPT_FN: | 
					
						
							| 
									
										
										
										
											2023-07-12 21:48:32 -04:00
										 |  |  | 		ret = opt->fn.parse(c, val, res, err); | 
					
						
							| 
									
										
										
										
											2022-06-04 14:49:02 -04:00
										 |  |  | 		if (ret < 0) { | 
					
						
							|  |  |  | 			if (err) | 
					
						
							| 
									
										
										
										
											2023-02-03 21:01:40 -05:00
										 |  |  | 				prt_printf(err, "%s: parse error", | 
					
						
							|  |  |  | 					   opt->attr.name); | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 			return ret; | 
					
						
							| 
									
										
										
										
											2022-06-04 14:49:02 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 	return bch2_opt_validate(opt, *res, err); | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-05 12:01:16 -05:00
										 |  |  | void bch2_opt_to_text(struct printbuf *out, | 
					
						
							|  |  |  | 		      struct bch_fs *c, struct bch_sb *sb, | 
					
						
							| 
									
										
										
										
											2018-11-09 01:24:07 -05:00
										 |  |  | 		      const struct bch_option *opt, u64 v, | 
					
						
							|  |  |  | 		      unsigned flags) | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (flags & OPT_SHOW_MOUNT_STYLE) { | 
					
						
							| 
									
										
										
										
											2018-11-09 01:24:07 -05:00
										 |  |  | 		if (opt->type == BCH_OPT_BOOL) { | 
					
						
							| 
									
										
										
										
											2023-02-03 21:01:40 -05:00
										 |  |  | 			prt_printf(out, "%s%s", | 
					
						
							| 
									
										
										
										
											2018-11-09 01:24:07 -05:00
										 |  |  | 			       v ? "" : "no", | 
					
						
							|  |  |  | 			       opt->attr.name); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-03 21:01:40 -05:00
										 |  |  | 		prt_printf(out, "%s=", opt->attr.name); | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (opt->type) { | 
					
						
							|  |  |  | 	case BCH_OPT_BOOL: | 
					
						
							|  |  |  | 	case BCH_OPT_UINT: | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		if (opt->flags & OPT_HUMAN_READABLE) | 
					
						
							| 
									
										
										
										
											2023-02-03 21:01:40 -05:00
										 |  |  | 			prt_human_readable_u64(out, v); | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2023-02-03 21:01:40 -05:00
										 |  |  | 			prt_printf(out, "%lli", v); | 
					
						
							| 
									
										
										
										
											2018-12-19 12:58:56 -05:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	case BCH_OPT_STR: | 
					
						
							| 
									
										
										
										
											2018-11-09 01:24:07 -05:00
										 |  |  | 		if (flags & OPT_SHOW_FULL_LIST) | 
					
						
							| 
									
										
										
										
											2023-02-03 21:01:40 -05:00
										 |  |  | 			prt_string_option(out, opt->choices, v); | 
					
						
							| 
									
										
										
										
											2018-11-09 01:24:07 -05:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | 			prt_str(out, opt->choices[v]); | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case BCH_OPT_FN: | 
					
						
							| 
									
										
										
										
											2023-07-12 21:48:32 -04:00
										 |  |  | 		opt->fn.to_text(out, c, sb, v); | 
					
						
							| 
									
										
										
										
											2018-11-09 01:24:07 -05:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 18:30:55 -05:00
										 |  |  | int bch2_opt_check_may_set(struct bch_fs *c, int id, u64 v) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int ret = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (id) { | 
					
						
							|  |  |  | 	case Opt_compression: | 
					
						
							|  |  |  | 	case Opt_background_compression: | 
					
						
							|  |  |  | 		ret = bch2_check_set_has_compressed_data(c, v); | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2018-11-01 15:13:19 -04:00
										 |  |  | 	case Opt_erasure_code: | 
					
						
							| 
									
										
										
										
											2019-11-29 13:47:42 -05:00
										 |  |  | 		if (v) | 
					
						
							| 
									
										
										
										
											2019-12-28 20:17:06 -05:00
										 |  |  | 			bch2_check_set_feature(c, BCH_FEATURE_ec); | 
					
						
							| 
									
										
										
										
											2018-11-01 15:13:19 -04:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2018-11-12 18:30:55 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-01 15:13:19 -04:00
										 |  |  | int bch2_opts_check_may_set(struct bch_fs *c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned i; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < bch2_opts_nr; i++) { | 
					
						
							|  |  |  | 		ret = bch2_opt_check_may_set(c, i, | 
					
						
							|  |  |  | 				bch2_opt_get_by_id(&c->opts, i)); | 
					
						
							|  |  |  | 		if (ret) | 
					
						
							|  |  |  | 			return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-23 21:07:17 -04:00
										 |  |  | int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts, | 
					
						
							|  |  |  | 			  char *options) | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-05-09 18:52:23 -04:00
										 |  |  | 	char *copied_opts, *copied_opts_start; | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	char *opt, *name, *val; | 
					
						
							|  |  |  | 	int ret, id; | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 	struct printbuf err = PRINTBUF; | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	u64 v; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-09 18:52:23 -04:00
										 |  |  | 	if (!options) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-02 12:51:51 -04:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * sys_fsconfig() is now occasionally providing us with option lists | 
					
						
							|  |  |  | 	 * starting with a comma - weird. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (*options == ',') | 
					
						
							|  |  |  | 		options++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-09 18:52:23 -04:00
										 |  |  | 	copied_opts = kstrdup(options, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!copied_opts) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	copied_opts_start = copied_opts; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while ((opt = strsep(&copied_opts, ",")) != NULL) { | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 		name	= strsep(&opt, "="); | 
					
						
							|  |  |  | 		val	= opt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | 		id = bch2_mount_opt_lookup(name); | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | 		/* Check for the form "noopt", negation of a boolean opt: */ | 
					
						
							|  |  |  | 		if (id < 0 && | 
					
						
							|  |  |  | 		    !val && | 
					
						
							|  |  |  | 		    !strncmp("no", name, 2)) { | 
					
						
							|  |  |  | 			id = bch2_mount_opt_lookup(name + 2); | 
					
						
							|  |  |  | 			val = "0"; | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-23 18:41:51 -04:00
										 |  |  | 		/* Unknown options are ignored: */ | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | 		if (id < 0) | 
					
						
							| 
									
										
										
										
											2023-09-23 18:41:51 -04:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		if (!(bch2_opt_table[id].flags & OPT_MOUNT)) | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 			goto bad_opt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (id == Opt_acl && | 
					
						
							|  |  |  | 		    !IS_ENABLED(CONFIG_BCACHEFS_POSIX_ACL)) | 
					
						
							|  |  |  | 			goto bad_opt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ((id == Opt_usrquota || | 
					
						
							|  |  |  | 		     id == Opt_grpquota) && | 
					
						
							|  |  |  | 		    !IS_ENABLED(CONFIG_BCACHEFS_QUOTA)) | 
					
						
							|  |  |  | 			goto bad_opt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 23:47:29 -04:00
										 |  |  | 		ret = bch2_opt_parse(c, &bch2_opt_table[id], val, &v, &err); | 
					
						
							|  |  |  | 		if (ret < 0) | 
					
						
							|  |  |  | 			goto bad_val; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 		bch2_opt_set_by_id(opts, id, v); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-09 18:52:23 -04:00
										 |  |  | 	ret = 0; | 
					
						
							|  |  |  | 	goto out; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | bad_opt: | 
					
						
							|  |  |  | 	pr_err("Bad mount option %s", name); | 
					
						
							| 
									
										
										
										
											2021-05-09 18:52:23 -04:00
										 |  |  | 	ret = -1; | 
					
						
							|  |  |  | 	goto out; | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | bad_val: | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 	pr_err("Invalid mount option %s", err.buf); | 
					
						
							| 
									
										
										
										
											2021-05-09 18:52:23 -04:00
										 |  |  | 	ret = -1; | 
					
						
							|  |  |  | 	goto out; | 
					
						
							|  |  |  | out: | 
					
						
							|  |  |  | 	kfree(copied_opts_start); | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 	printbuf_exit(&err); | 
					
						
							| 
									
										
										
										
											2021-05-09 18:52:23 -04:00
										 |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-05 12:01:16 -05:00
										 |  |  | u64 bch2_opt_from_sb(struct bch_sb *sb, enum bch_opt_id id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const struct bch_option *opt = bch2_opt_table + id; | 
					
						
							|  |  |  | 	u64 v; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	v = opt->get_sb(sb); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (opt->flags & OPT_SB_FIELD_ILOG2) | 
					
						
							|  |  |  | 		v = 1ULL << v; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (opt->flags & OPT_SB_FIELD_SECTORS) | 
					
						
							|  |  |  | 		v <<= 9; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Initial options from superblock - here we don't want any options undefined, | 
					
						
							|  |  |  |  * any options the superblock doesn't specify are set to 0: | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int bch2_opts_from_sb(struct bch_opts *opts, struct bch_sb *sb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (id = 0; id < bch2_opts_nr; id++) { | 
					
						
							|  |  |  | 		const struct bch_option *opt = bch2_opt_table + id; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-05 12:01:16 -05:00
										 |  |  | 		if (opt->get_sb == BCH2_NO_SB_OPT) | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-21 00:15:38 -04:00
										 |  |  | 		bch2_opt_set_by_id(opts, id, bch2_opt_from_sb(sb, id)); | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void __bch2_opt_set_sb(struct bch_sb *sb, const struct bch_option *opt, u64 v) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-03-05 12:01:16 -05:00
										 |  |  | 	if (opt->set_sb == SET_BCH2_NO_SB_OPT) | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (opt->flags & OPT_SB_FIELD_SECTORS) | 
					
						
							|  |  |  | 		v >>= 9; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (opt->flags & OPT_SB_FIELD_ILOG2) | 
					
						
							|  |  |  | 		v = ilog2(v); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	opt->set_sb(sb, v); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void bch2_opt_set_sb(struct bch_fs *c, const struct bch_option *opt, u64 v) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-03-05 12:01:16 -05:00
										 |  |  | 	if (opt->set_sb == SET_BCH2_NO_SB_OPT) | 
					
						
							| 
									
										
										
										
											2021-12-14 14:24:41 -05:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mutex_lock(&c->sb_lock); | 
					
						
							|  |  |  | 	__bch2_opt_set_sb(c->disk_sb.sb, opt, v); | 
					
						
							|  |  |  | 	bch2_write_super(c); | 
					
						
							|  |  |  | 	mutex_unlock(&c->sb_lock); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | /* io opts: */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct bch_io_opts bch2_opts_to_inode_opts(struct bch_opts src) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-11-23 20:14:55 -05:00
										 |  |  | 	return (struct bch_io_opts) { | 
					
						
							|  |  |  | #define x(_name, _bits)	._name = src._name,
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	BCH_INODE_OPTS() | 
					
						
							| 
									
										
										
										
											2018-12-13 06:01:30 -05:00
										 |  |  | #undef x
 | 
					
						
							| 
									
										
										
										
											2022-11-23 20:14:55 -05:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool bch2_opt_is_inode_opt(enum bch_opt_id id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static const enum bch_opt_id inode_opt_list[] = { | 
					
						
							| 
									
										
										
										
											2018-12-13 06:01:30 -05:00
										 |  |  | #define x(_name, _bits)	Opt_##_name,
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	BCH_INODE_OPTS() | 
					
						
							| 
									
										
										
										
											2018-12-13 06:01:30 -05:00
										 |  |  | #undef x
 | 
					
						
							| 
									
										
										
										
											2017-03-16 22:18:50 -08:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 	unsigned i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < ARRAY_SIZE(inode_opt_list); i++) | 
					
						
							|  |  |  | 		if (inode_opt_list[i] == id) | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } |