1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _BCACHEFS_OPTS_H
3#define _BCACHEFS_OPTS_H
4
5#include <linux/bug.h>
6#include <linux/log2.h>
7#include <linux/string.h>
8#include <linux/sysfs.h>
9#include "bcachefs_format.h"
10
11struct bch_fs;
12
13extern const char * const bch2_error_actions[];
14extern const char * const bch2_fsck_fix_opts[];
15extern const char * const bch2_version_upgrade_opts[];
16extern const char * const bch2_sb_features[];
17extern const char * const bch2_sb_compat[];
18extern const char * const __bch2_btree_ids[];
19extern const char * const bch2_csum_opts[];
20extern const char * const bch2_compression_opts[];
21extern const char * const bch2_str_hash_types[];
22extern const char * const bch2_str_hash_opts[];
23extern const char * const __bch2_data_types[];
24extern const char * const bch2_member_states[];
25extern const char * const bch2_d_types[];
26
27void bch2_prt_jset_entry_type(struct printbuf *,	enum bch_jset_entry_type);
28void bch2_prt_fs_usage_type(struct printbuf *,		enum bch_fs_usage_type);
29void bch2_prt_data_type(struct printbuf *,		enum bch_data_type);
30void bch2_prt_csum_type(struct printbuf *,		enum bch_csum_type);
31void bch2_prt_compression_type(struct printbuf *,	enum bch_compression_type);
32
33static inline const char *bch2_d_type_str(unsigned d_type)
34{
35	return (d_type < BCH_DT_MAX ? bch2_d_types[d_type] : NULL) ?: "(bad d_type)";
36}
37
38/*
39 * Mount options; we also store defaults in the superblock.
40 *
41 * Also exposed via sysfs: if an option is writeable, and it's also stored in
42 * the superblock, changing it via sysfs (currently? might change this) also
43 * updates the superblock.
44 *
45 * We store options as signed integers, where -1 means undefined. This means we
46 * can pass the mount options to bch2_fs_alloc() as a whole struct, and then only
47 * apply the options from that struct that are defined.
48 */
49
50/* dummy option, for options that aren't stored in the superblock */
51u64 BCH2_NO_SB_OPT(const struct bch_sb *);
52void SET_BCH2_NO_SB_OPT(struct bch_sb *, u64);
53
54/* When can be set: */
55enum opt_flags {
56	OPT_FS		= (1 << 0),	/* Filesystem option */
57	OPT_DEVICE	= (1 << 1),	/* Device option */
58	OPT_INODE	= (1 << 2),	/* Inode option */
59	OPT_FORMAT	= (1 << 3),	/* May be specified at format time */
60	OPT_MOUNT	= (1 << 4),	/* May be specified at mount time */
61	OPT_RUNTIME	= (1 << 5),	/* May be specified at runtime */
62	OPT_HUMAN_READABLE = (1 << 6),
63	OPT_MUST_BE_POW_2 = (1 << 7),	/* Must be power of 2 */
64	OPT_SB_FIELD_SECTORS = (1 << 8),/* Superblock field is >> 9 of actual value */
65	OPT_SB_FIELD_ILOG2 = (1 << 9),	/* Superblock field is ilog2 of actual value */
66};
67
68enum opt_type {
69	BCH_OPT_BOOL,
70	BCH_OPT_UINT,
71	BCH_OPT_STR,
72	BCH_OPT_FN,
73};
74
75struct bch_opt_fn {
76	int (*parse)(struct bch_fs *, const char *, u64 *, struct printbuf *);
77	void (*to_text)(struct printbuf *, struct bch_fs *, struct bch_sb *, u64);
78	int (*validate)(u64, struct printbuf *);
79};
80
81/**
82 * x(name, shortopt, type, in mem type, mode, sb_opt)
83 *
84 * @name	- name of mount option, sysfs attribute, and struct bch_opts
85 *		  member
86 *
87 * @mode	- when opt may be set
88 *
89 * @sb_option	- name of corresponding superblock option
90 *
91 * @type	- one of OPT_BOOL, OPT_UINT, OPT_STR
92 */
93
94/*
95 * XXX: add fields for
96 *  - default value
97 *  - helptext
98 */
99
100#ifdef __KERNEL__
101#define RATELIMIT_ERRORS_DEFAULT true
102#else
103#define RATELIMIT_ERRORS_DEFAULT false
104#endif
105
106#ifdef CONFIG_BCACHEFS_DEBUG
107#define BCACHEFS_VERBOSE_DEFAULT	true
108#else
109#define BCACHEFS_VERBOSE_DEFAULT	false
110#endif
111
112#define BCH_FIX_ERRORS_OPTS()		\
113	x(exit,	0)			\
114	x(yes,	1)			\
115	x(no,	2)			\
116	x(ask,	3)
117
118enum fsck_err_opts {
119#define x(t, n)	FSCK_FIX_##t,
120	BCH_FIX_ERRORS_OPTS()
121#undef x
122};
123
124#define BCH_OPTS()							\
125	x(block_size,			u16,				\
126	  OPT_FS|OPT_FORMAT|						\
127	  OPT_HUMAN_READABLE|OPT_MUST_BE_POW_2|OPT_SB_FIELD_SECTORS,	\
128	  OPT_UINT(512, 1U << 16),					\
129	  BCH_SB_BLOCK_SIZE,		8,				\
130	  "size",	NULL)						\
131	x(btree_node_size,		u32,				\
132	  OPT_FS|OPT_FORMAT|						\
133	  OPT_HUMAN_READABLE|OPT_MUST_BE_POW_2|OPT_SB_FIELD_SECTORS,	\
134	  OPT_UINT(512, 1U << 20),					\
135	  BCH_SB_BTREE_NODE_SIZE,	512,				\
136	  "size",	"Btree node size, default 256k")		\
137	x(errors,			u8,				\
138	  OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,			\
139	  OPT_STR(bch2_error_actions),					\
140	  BCH_SB_ERROR_ACTION,		BCH_ON_ERROR_ro,		\
141	  NULL,		"Action to take on filesystem error")		\
142	x(metadata_replicas,		u8,				\
143	  OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,			\
144	  OPT_UINT(1, BCH_REPLICAS_MAX),				\
145	  BCH_SB_META_REPLICAS_WANT,	1,				\
146	  "#",		"Number of metadata replicas")			\
147	x(data_replicas,		u8,				\
148	  OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,		\
149	  OPT_UINT(1, BCH_REPLICAS_MAX),				\
150	  BCH_SB_DATA_REPLICAS_WANT,	1,				\
151	  "#",		"Number of data replicas")			\
152	x(metadata_replicas_required, u8,				\
153	  OPT_FS|OPT_FORMAT|OPT_MOUNT,					\
154	  OPT_UINT(1, BCH_REPLICAS_MAX),				\
155	  BCH_SB_META_REPLICAS_REQ,	1,				\
156	  "#",		NULL)						\
157	x(data_replicas_required,	u8,				\
158	  OPT_FS|OPT_FORMAT|OPT_MOUNT,					\
159	  OPT_UINT(1, BCH_REPLICAS_MAX),				\
160	  BCH_SB_DATA_REPLICAS_REQ,	1,				\
161	  "#",		NULL)						\
162	x(encoded_extent_max,		u32,				\
163	  OPT_FS|OPT_FORMAT|						\
164	  OPT_HUMAN_READABLE|OPT_MUST_BE_POW_2|OPT_SB_FIELD_SECTORS|OPT_SB_FIELD_ILOG2,\
165	  OPT_UINT(4096, 2U << 20),					\
166	  BCH_SB_ENCODED_EXTENT_MAX_BITS, 64 << 10,			\
167	  "size",	"Maximum size of checksummed/compressed extents")\
168	x(metadata_checksum,		u8,				\
169	  OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,			\
170	  OPT_STR(bch2_csum_opts),					\
171	  BCH_SB_META_CSUM_TYPE,	BCH_CSUM_OPT_crc32c,		\
172	  NULL,		NULL)						\
173	x(data_checksum,		u8,				\
174	  OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,		\
175	  OPT_STR(bch2_csum_opts),					\
176	  BCH_SB_DATA_CSUM_TYPE,	BCH_CSUM_OPT_crc32c,		\
177	  NULL,		NULL)						\
178	x(compression,			u8,				\
179	  OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,		\
180	  OPT_FN(bch2_opt_compression),					\
181	  BCH_SB_COMPRESSION_TYPE,	BCH_COMPRESSION_OPT_none,	\
182	  NULL,		NULL)						\
183	x(background_compression,	u8,				\
184	  OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,		\
185	  OPT_FN(bch2_opt_compression),					\
186	  BCH_SB_BACKGROUND_COMPRESSION_TYPE,BCH_COMPRESSION_OPT_none,	\
187	  NULL,		NULL)						\
188	x(str_hash,			u8,				\
189	  OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,			\
190	  OPT_STR(bch2_str_hash_opts),					\
191	  BCH_SB_STR_HASH_TYPE,		BCH_STR_HASH_OPT_siphash,	\
192	  NULL,		"Hash function for directory entries and xattrs")\
193	x(metadata_target,		u16,				\
194	  OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,		\
195	  OPT_FN(bch2_opt_target),					\
196	  BCH_SB_METADATA_TARGET,	0,				\
197	  "(target)",	"Device or label for metadata writes")		\
198	x(foreground_target,		u16,				\
199	  OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,		\
200	  OPT_FN(bch2_opt_target),					\
201	  BCH_SB_FOREGROUND_TARGET,	0,				\
202	  "(target)",	"Device or label for foreground writes")	\
203	x(background_target,		u16,				\
204	  OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,		\
205	  OPT_FN(bch2_opt_target),					\
206	  BCH_SB_BACKGROUND_TARGET,	0,				\
207	  "(target)",	"Device or label to move data to in the background")\
208	x(promote_target,		u16,				\
209	  OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,		\
210	  OPT_FN(bch2_opt_target),					\
211	  BCH_SB_PROMOTE_TARGET,	0,				\
212	  "(target)",	"Device or label to promote data to on read")	\
213	x(erasure_code,			u16,				\
214	  OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,		\
215	  OPT_BOOL(),							\
216	  BCH_SB_ERASURE_CODE,		false,				\
217	  NULL,		"Enable erasure coding (DO NOT USE YET)")	\
218	x(inodes_32bit,			u8,				\
219	  OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,			\
220	  OPT_BOOL(),							\
221	  BCH_SB_INODE_32BIT,		true,				\
222	  NULL,		"Constrain inode numbers to 32 bits")		\
223	x(shard_inode_numbers,		u8,				\
224	  OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,			\
225	  OPT_BOOL(),							\
226	  BCH_SB_SHARD_INUMS,		true,				\
227	  NULL,		"Shard new inode numbers by CPU id")		\
228	x(inodes_use_key_cache,	u8,					\
229	  OPT_FS|OPT_FORMAT|OPT_MOUNT,					\
230	  OPT_BOOL(),							\
231	  BCH_SB_INODES_USE_KEY_CACHE,	true,				\
232	  NULL,		"Use the btree key cache for the inodes btree")	\
233	x(btree_node_mem_ptr_optimization, u8,				\
234	  OPT_FS|OPT_MOUNT|OPT_RUNTIME,					\
235	  OPT_BOOL(),							\
236	  BCH2_NO_SB_OPT,		true,				\
237	  NULL,		"Stash pointer to in memory btree node in btree ptr")\
238	x(gc_reserve_percent,		u8,				\
239	  OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,			\
240	  OPT_UINT(5, 21),						\
241	  BCH_SB_GC_RESERVE,		8,				\
242	  "%",		"Percentage of disk space to reserve for copygc")\
243	x(gc_reserve_bytes,		u64,				\
244	  OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME|			\
245	  OPT_HUMAN_READABLE|OPT_SB_FIELD_SECTORS,			\
246	  OPT_UINT(0, U64_MAX),						\
247	  BCH_SB_GC_RESERVE_BYTES,	0,				\
248	  "%",		"Amount of disk space to reserve for copygc\n"	\
249			"Takes precedence over gc_reserve_percent if set")\
250	x(root_reserve_percent,		u8,				\
251	  OPT_FS|OPT_FORMAT|OPT_MOUNT,					\
252	  OPT_UINT(0, 100),						\
253	  BCH_SB_ROOT_RESERVE,		0,				\
254	  "%",		"Percentage of disk space to reserve for superuser")\
255	x(wide_macs,			u8,				\
256	  OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,			\
257	  OPT_BOOL(),							\
258	  BCH_SB_128_BIT_MACS,		false,				\
259	  NULL,		"Store full 128 bits of cryptographic MACs, instead of 80")\
260	x(inline_data,			u8,				\
261	  OPT_FS|OPT_MOUNT|OPT_RUNTIME,					\
262	  OPT_BOOL(),							\
263	  BCH2_NO_SB_OPT,		true,				\
264	  NULL,		"Enable inline data extents")			\
265	x(acl,				u8,				\
266	  OPT_FS|OPT_FORMAT|OPT_MOUNT,					\
267	  OPT_BOOL(),							\
268	  BCH_SB_POSIX_ACL,		true,				\
269	  NULL,		"Enable POSIX acls")				\
270	x(usrquota,			u8,				\
271	  OPT_FS|OPT_FORMAT|OPT_MOUNT,					\
272	  OPT_BOOL(),							\
273	  BCH_SB_USRQUOTA,		false,				\
274	  NULL,		"Enable user quotas")				\
275	x(grpquota,			u8,				\
276	  OPT_FS|OPT_FORMAT|OPT_MOUNT,					\
277	  OPT_BOOL(),							\
278	  BCH_SB_GRPQUOTA,		false,				\
279	  NULL,		"Enable group quotas")				\
280	x(prjquota,			u8,				\
281	  OPT_FS|OPT_FORMAT|OPT_MOUNT,					\
282	  OPT_BOOL(),							\
283	  BCH_SB_PRJQUOTA,		false,				\
284	  NULL,		"Enable project quotas")			\
285	x(degraded,			u8,				\
286	  OPT_FS|OPT_MOUNT,						\
287	  OPT_BOOL(),							\
288	  BCH2_NO_SB_OPT,		false,				\
289	  NULL,		"Allow mounting in degraded mode")		\
290	x(very_degraded,		u8,				\
291	  OPT_FS|OPT_MOUNT,						\
292	  OPT_BOOL(),							\
293	  BCH2_NO_SB_OPT,		false,				\
294	  NULL,		"Allow mounting in when data will be missing")	\
295	x(no_splitbrain_check,		u8,				\
296	  OPT_FS|OPT_MOUNT,						\
297	  OPT_BOOL(),							\
298	  BCH2_NO_SB_OPT,		false,				\
299	  NULL,		"Don't kick drives out when splitbrain detected")\
300	x(discard,			u8,				\
301	  OPT_FS|OPT_MOUNT|OPT_DEVICE,					\
302	  OPT_BOOL(),							\
303	  BCH2_NO_SB_OPT,		true,				\
304	  NULL,		"Enable discard/TRIM support")			\
305	x(verbose,			u8,				\
306	  OPT_FS|OPT_MOUNT|OPT_RUNTIME,					\
307	  OPT_BOOL(),							\
308	  BCH2_NO_SB_OPT,		BCACHEFS_VERBOSE_DEFAULT,	\
309	  NULL,		"Extra debugging information during mount/recovery")\
310	x(journal_flush_delay,		u32,				\
311	  OPT_FS|OPT_MOUNT|OPT_RUNTIME,					\
312	  OPT_UINT(1, U32_MAX),						\
313	  BCH_SB_JOURNAL_FLUSH_DELAY,	1000,				\
314	  NULL,		"Delay in milliseconds before automatic journal commits")\
315	x(journal_flush_disabled,	u8,				\
316	  OPT_FS|OPT_MOUNT|OPT_RUNTIME,					\
317	  OPT_BOOL(),							\
318	  BCH_SB_JOURNAL_FLUSH_DISABLED,false,				\
319	  NULL,		"Disable journal flush on sync/fsync\n"		\
320			"If enabled, writes can be lost, but only since the\n"\
321			"last journal write (default 1 second)")	\
322	x(journal_reclaim_delay,	u32,				\
323	  OPT_FS|OPT_MOUNT|OPT_RUNTIME,					\
324	  OPT_UINT(0, U32_MAX),						\
325	  BCH_SB_JOURNAL_RECLAIM_DELAY,	100,				\
326	  NULL,		"Delay in milliseconds before automatic journal reclaim")\
327	x(move_bytes_in_flight,		u32,				\
328	  OPT_HUMAN_READABLE|OPT_FS|OPT_MOUNT|OPT_RUNTIME,		\
329	  OPT_UINT(1024, U32_MAX),					\
330	  BCH2_NO_SB_OPT,		1U << 20,			\
331	  NULL,		"Maximum Amount of IO to keep in flight by the move path")\
332	x(move_ios_in_flight,		u32,				\
333	  OPT_FS|OPT_MOUNT|OPT_RUNTIME,					\
334	  OPT_UINT(1, 1024),						\
335	  BCH2_NO_SB_OPT,		32,				\
336	  NULL,		"Maximum number of IOs to keep in flight by the move path")\
337	x(fsck,				u8,				\
338	  OPT_FS|OPT_MOUNT,						\
339	  OPT_BOOL(),							\
340	  BCH2_NO_SB_OPT,		false,				\
341	  NULL,		"Run fsck on mount")				\
342	x(fsck_memory_usage_percent,	u8,				\
343	  OPT_FS|OPT_MOUNT,						\
344	  OPT_UINT(20, 70),						\
345	  BCH2_NO_SB_OPT,		50,				\
346	  NULL,		"Maximum percentage of system ram fsck is allowed to pin")\
347	x(fix_errors,			u8,				\
348	  OPT_FS|OPT_MOUNT,						\
349	  OPT_FN(bch2_opt_fix_errors),					\
350	  BCH2_NO_SB_OPT,		FSCK_FIX_exit,			\
351	  NULL,		"Fix errors during fsck without asking")	\
352	x(ratelimit_errors,		u8,				\
353	  OPT_FS|OPT_MOUNT,						\
354	  OPT_BOOL(),							\
355	  BCH2_NO_SB_OPT,		RATELIMIT_ERRORS_DEFAULT,	\
356	  NULL,		"Ratelimit error messages during fsck")		\
357	x(nochanges,			u8,				\
358	  OPT_FS|OPT_MOUNT,						\
359	  OPT_BOOL(),							\
360	  BCH2_NO_SB_OPT,		false,				\
361	  NULL,		"Super read only mode - no writes at all will be issued,\n"\
362			"even if we have to replay the journal")	\
363	x(norecovery,			u8,				\
364	  OPT_FS|OPT_MOUNT,						\
365	  OPT_BOOL(),							\
366	  BCH2_NO_SB_OPT,		false,				\
367	  NULL,		"Exit recovery immediately prior to journal replay")\
368	x(recovery_pass_last,		u8,				\
369	  OPT_FS|OPT_MOUNT,						\
370	  OPT_STR_NOLIMIT(bch2_recovery_passes),			\
371	  BCH2_NO_SB_OPT,		0,				\
372	  NULL,		"Exit recovery after specified pass")		\
373	x(retain_recovery_info,		u8,				\
374	  0,								\
375	  OPT_BOOL(),							\
376	  BCH2_NO_SB_OPT,		false,				\
377	  NULL,		"Don't free journal entries/keys, scanned btree nodes after startup")\
378	x(read_entire_journal,		u8,				\
379	  0,								\
380	  OPT_BOOL(),							\
381	  BCH2_NO_SB_OPT,		false,				\
382	  NULL,		"Read all journal entries, not just dirty ones")\
383	x(read_journal_only,		u8,				\
384	  0,								\
385	  OPT_BOOL(),							\
386	  BCH2_NO_SB_OPT,		false,				\
387	  NULL,		"Only read the journal, skip the rest of recovery")\
388	x(journal_transaction_names,	u8,				\
389	  OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,			\
390	  OPT_BOOL(),							\
391	  BCH_SB_JOURNAL_TRANSACTION_NAMES, true,			\
392	  NULL,		"Log transaction function names in journal")	\
393	x(noexcl,			u8,				\
394	  OPT_FS|OPT_MOUNT,						\
395	  OPT_BOOL(),							\
396	  BCH2_NO_SB_OPT,		false,				\
397	  NULL,		"Don't open device in exclusive mode")		\
398	x(direct_io,			u8,				\
399	  OPT_FS|OPT_MOUNT,						\
400	  OPT_BOOL(),							\
401	  BCH2_NO_SB_OPT,			true,			\
402	  NULL,		"Use O_DIRECT (userspace only)")		\
403	x(sb,				u64,				\
404	  OPT_MOUNT,							\
405	  OPT_UINT(0, S64_MAX),						\
406	  BCH2_NO_SB_OPT,		BCH_SB_SECTOR,			\
407	  "offset",	"Sector offset of superblock")			\
408	x(read_only,			u8,				\
409	  OPT_FS|OPT_MOUNT,						\
410	  OPT_BOOL(),							\
411	  BCH2_NO_SB_OPT,		false,				\
412	  NULL,		NULL)						\
413	x(nostart,			u8,				\
414	  0,								\
415	  OPT_BOOL(),							\
416	  BCH2_NO_SB_OPT,		false,				\
417	  NULL,		"Don\'t start filesystem, only open devices")	\
418	x(reconstruct_alloc,		u8,				\
419	  OPT_FS|OPT_MOUNT,						\
420	  OPT_BOOL(),							\
421	  BCH2_NO_SB_OPT,		false,				\
422	  NULL,		"Reconstruct alloc btree")			\
423	x(version_upgrade,		u8,				\
424	  OPT_FS|OPT_MOUNT,						\
425	  OPT_STR(bch2_version_upgrade_opts),				\
426	  BCH_SB_VERSION_UPGRADE,	BCH_VERSION_UPGRADE_compatible,	\
427	  NULL,		"Set superblock to latest version,\n"		\
428			"allowing any new features to be used")		\
429	x(buckets_nouse,		u8,				\
430	  0,								\
431	  OPT_BOOL(),							\
432	  BCH2_NO_SB_OPT,		false,				\
433	  NULL,		"Allocate the buckets_nouse bitmap")		\
434	x(stdio,			u64,				\
435	  0,								\
436	  OPT_UINT(0, S64_MAX),						\
437	  BCH2_NO_SB_OPT,		false,				\
438	  NULL,		"Pointer to a struct stdio_redirect")		\
439	x(project,			u8,				\
440	  OPT_INODE,							\
441	  OPT_BOOL(),							\
442	  BCH2_NO_SB_OPT,		false,				\
443	  NULL,		NULL)						\
444	x(nocow,			u8,				\
445	  OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME|OPT_INODE,		\
446	  OPT_BOOL(),							\
447	  BCH_SB_NOCOW,			false,				\
448	  NULL,		"Nocow mode: Writes will be done in place when possible.\n"\
449			"Snapshots and reflink will still caused writes to be COW\n"\
450			"Implicitly disables data checksumming, compression and encryption")\
451	x(nocow_enabled,		u8,				\
452	  OPT_FS|OPT_MOUNT,						\
453	  OPT_BOOL(),							\
454	  BCH2_NO_SB_OPT,			true,			\
455	  NULL,		"Enable nocow mode: enables runtime locking in\n"\
456			"data move path needed if nocow will ever be in use\n")\
457	x(no_data_io,			u8,				\
458	  OPT_MOUNT,							\
459	  OPT_BOOL(),							\
460	  BCH2_NO_SB_OPT,		false,				\
461	  NULL,		"Skip submit_bio() for data reads and writes, "	\
462			"for performance testing purposes")		\
463	x(fs_size,			u64,				\
464	  OPT_DEVICE,							\
465	  OPT_UINT(0, S64_MAX),						\
466	  BCH2_NO_SB_OPT,		0,				\
467	  "size",	"Size of filesystem on device")			\
468	x(bucket,			u32,				\
469	  OPT_DEVICE,							\
470	  OPT_UINT(0, S64_MAX),						\
471	  BCH2_NO_SB_OPT,		0,				\
472	  "size",	"Size of filesystem on device")			\
473	x(durability,			u8,				\
474	  OPT_DEVICE,							\
475	  OPT_UINT(0, BCH_REPLICAS_MAX),				\
476	  BCH2_NO_SB_OPT,		1,				\
477	  "n",		"Data written to this device will be considered\n"\
478			"to have already been replicated n times")	\
479	x(btree_node_prefetch,		u8,				\
480	  OPT_FS|OPT_MOUNT|OPT_RUNTIME,					\
481	  OPT_BOOL(),							\
482	  BCH2_NO_SB_OPT,		true,				\
483	  NULL,		"BTREE_ITER_PREFETCH casuse btree nodes to be\n"\
484	  " prefetched sequentially")
485
486struct bch_opts {
487#define x(_name, _bits, ...)	unsigned _name##_defined:1;
488	BCH_OPTS()
489#undef x
490
491#define x(_name, _bits, ...)	_bits	_name;
492	BCH_OPTS()
493#undef x
494};
495
496static const __maybe_unused struct bch_opts bch2_opts_default = {
497#define x(_name, _bits, _mode, _type, _sb_opt, _default, ...)		\
498	._name##_defined = true,					\
499	._name = _default,						\
500
501	BCH_OPTS()
502#undef x
503};
504
505#define opt_defined(_opts, _name)	((_opts)._name##_defined)
506
507#define opt_get(_opts, _name)						\
508	(opt_defined(_opts, _name) ? (_opts)._name : bch2_opts_default._name)
509
510#define opt_set(_opts, _name, _v)					\
511do {									\
512	(_opts)._name##_defined = true;					\
513	(_opts)._name = _v;						\
514} while (0)
515
516static inline struct bch_opts bch2_opts_empty(void)
517{
518	return (struct bch_opts) { 0 };
519}
520
521void bch2_opts_apply(struct bch_opts *, struct bch_opts);
522
523enum bch_opt_id {
524#define x(_name, ...)	Opt_##_name,
525	BCH_OPTS()
526#undef x
527	bch2_opts_nr
528};
529
530struct bch_fs;
531struct printbuf;
532
533struct bch_option {
534	struct attribute	attr;
535	u64			(*get_sb)(const struct bch_sb *);
536	void			(*set_sb)(struct bch_sb *, u64);
537	enum opt_type		type;
538	enum opt_flags		flags;
539	u64			min, max;
540
541	const char * const *choices;
542
543	struct bch_opt_fn	fn;
544
545	const char		*hint;
546	const char		*help;
547
548};
549
550extern const struct bch_option bch2_opt_table[];
551
552bool bch2_opt_defined_by_id(const struct bch_opts *, enum bch_opt_id);
553u64 bch2_opt_get_by_id(const struct bch_opts *, enum bch_opt_id);
554void bch2_opt_set_by_id(struct bch_opts *, enum bch_opt_id, u64);
555
556u64 bch2_opt_from_sb(struct bch_sb *, enum bch_opt_id);
557int bch2_opts_from_sb(struct bch_opts *, struct bch_sb *);
558void __bch2_opt_set_sb(struct bch_sb *, const struct bch_option *, u64);
559void bch2_opt_set_sb(struct bch_fs *, const struct bch_option *, u64);
560
561int bch2_opt_lookup(const char *);
562int bch2_opt_validate(const struct bch_option *, u64, struct printbuf *);
563int bch2_opt_parse(struct bch_fs *, const struct bch_option *,
564		   const char *, u64 *, struct printbuf *);
565
566#define OPT_SHOW_FULL_LIST	(1 << 0)
567#define OPT_SHOW_MOUNT_STYLE	(1 << 1)
568
569void bch2_opt_to_text(struct printbuf *, struct bch_fs *, struct bch_sb *,
570		      const struct bch_option *, u64, unsigned);
571
572int bch2_opt_check_may_set(struct bch_fs *, int, u64);
573int bch2_opts_check_may_set(struct bch_fs *);
574int bch2_parse_mount_opts(struct bch_fs *, struct bch_opts *, char *);
575
576/* inode opts: */
577
578struct bch_io_opts {
579#define x(_name, _bits)	u##_bits _name;
580	BCH_INODE_OPTS()
581#undef x
582};
583
584static inline unsigned background_compression(struct bch_io_opts opts)
585{
586	return opts.background_compression ?: opts.compression;
587}
588
589struct bch_io_opts bch2_opts_to_inode_opts(struct bch_opts);
590bool bch2_opt_is_inode_opt(enum bch_opt_id);
591
592#endif /* _BCACHEFS_OPTS_H */
593