summaryrefslogtreecommitdiff
path: root/libbcache/opts.h
blob: 9b10310d1e21f966036a1f4c862d1daf2ab46da2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#ifndef _BCACHE_OPTS_H
#define _BCACHE_OPTS_H

#include <linux/bcache.h>
#include <linux/bug.h>
#include <linux/log2.h>
#include <linux/string.h>

extern const char * const bch_error_actions[];
extern const char * const bch_csum_types[];
extern const char * const bch_compression_types[];
extern const char * const bch_str_hash_types[];
extern const char * const bch_cache_replacement_policies[];
extern const char * const bch_cache_modes[];
extern const char * const bch_dev_state[];

/*
 * Mount options; we also store defaults in the superblock.
 *
 * Also exposed via sysfs: if an option is writeable, and it's also stored in
 * the superblock, changing it via sysfs (currently? might change this) also
 * updates the superblock.
 *
 * We store options as signed integers, where -1 means undefined. This means we
 * can pass the mount options to bch_fs_alloc() as a whole struct, and then only
 * apply the options from that struct that are defined.
 */

/* dummy option, for options that aren't stored in the superblock */
LE64_BITMASK(NO_SB_OPT,		struct bch_sb, flags[0], 0, 0);

/**
 * BCH_OPT(name, mode, sb_opt, type, ...)
 *
 * @name	- name of mount option, sysfs attribute, and struct bch_opts
 *		  member
 *
 * @mode	- sysfs attr permissions
 *
 * @sb_option	- name of corresponding superblock option
 *
 * @type	- one of OPT_BOOL, OPT_UINT, OPT_STR
 */

enum opt_type {
	BCH_OPT_BOOL,
	BCH_OPT_UINT,
	BCH_OPT_STR,
};

#define BCH_VISIBLE_OPTS()						\
	BCH_OPT(errors,			0644,	BCH_SB_ERROR_ACTION,	\
		s8,  OPT_STR(bch_error_actions))			\
	BCH_OPT(metadata_replicas,	0444,	BCH_SB_META_REPLICAS_WANT,\
		s8,  OPT_UINT(0, BCH_REPLICAS_MAX))			\
	BCH_OPT(data_replicas,		0444,	BCH_SB_DATA_REPLICAS_WANT,\
		s8,  OPT_UINT(0, BCH_REPLICAS_MAX))			\
	BCH_OPT(metadata_checksum,	0644,	BCH_SB_META_CSUM_TYPE,	\
		s8,  OPT_STR(bch_csum_types))				\
	BCH_OPT(data_checksum,		0644,	BCH_SB_DATA_CSUM_TYPE,	\
		s8,  OPT_STR(bch_csum_types))				\
	BCH_OPT(compression,		0644,	BCH_SB_COMPRESSION_TYPE,\
		s8,  OPT_STR(bch_compression_types))			\
	BCH_OPT(str_hash,		0644,	BCH_SB_STR_HASH_TYPE,	\
		s8,  OPT_STR(bch_str_hash_types))			\
	BCH_OPT(inodes_32bit,		0644,	BCH_SB_INODE_32BIT,	\
		s8,  OPT_BOOL())					\
	BCH_OPT(gc_reserve_percent,	0444,	BCH_SB_GC_RESERVE,	\
		s8,  OPT_UINT(5, 21))					\
	BCH_OPT(root_reserve_percent,	0444,	BCH_SB_ROOT_RESERVE,	\
		s8,  OPT_UINT(0, 100))					\
	BCH_OPT(wide_macs,		0644,	BCH_SB_128_BIT_MACS,	\
		s8,  OPT_BOOL())					\
	BCH_OPT(verbose_recovery,	0444,	NO_SB_OPT,		\
		s8,  OPT_BOOL())					\
	BCH_OPT(posix_acl,		0444,	NO_SB_OPT,		\
		s8,  OPT_BOOL())					\
	BCH_OPT(journal_flush_disabled,	0644,	NO_SB_OPT,		\
		s8,  OPT_BOOL())					\
	BCH_OPT(nofsck,			0444,	NO_SB_OPT,		\
		s8,  OPT_BOOL())					\
	BCH_OPT(fix_errors,		0444,	NO_SB_OPT,		\
		s8,  OPT_BOOL())					\
	BCH_OPT(nochanges,		0444,	NO_SB_OPT,		\
		s8,  OPT_BOOL())					\
	BCH_OPT(noreplay,		0444,	NO_SB_OPT,		\
		s8,  OPT_BOOL())					\
	BCH_OPT(norecovery,		0444,	NO_SB_OPT,		\
		s8,  OPT_BOOL())					\
	BCH_OPT(noexcl,			0444,	NO_SB_OPT,		\
		s8,  OPT_BOOL())					\
	BCH_OPT(sb,			0444,	NO_SB_OPT,		\
		s64, OPT_UINT(0, S64_MAX))				\

#define BCH_OPTS()							\
	BCH_OPT(read_only,		0444,	NO_SB_OPT,		\
		s8,  OPT_BOOL())					\
	BCH_OPT(nostart,		0444,	NO_SB_OPT,		\
		s8,  OPT_BOOL())					\
	BCH_VISIBLE_OPTS()

struct bch_opts {
#define BCH_OPT(_name, _mode, _sb_opt, _bits, ...)			\
	_bits	_name;

	BCH_OPTS()
#undef BCH_OPT
};

enum bch_opt_id {
#define BCH_OPT(_name, ...)			\
	Opt_##_name,

	BCH_VISIBLE_OPTS()
#undef BCH_OPT
};

struct bch_option {
	const char		*name;
	void			(*set_sb)(struct bch_sb *, u64);
	enum opt_type		type;

	union {
	struct {
		u64		min, max;
	};
	struct {
		const char * const *choices;
	};
	};

};

extern const struct bch_option bch_opt_table[];

static inline struct bch_opts bch_opts_empty(void)
{
	struct bch_opts ret;

	memset(&ret, 255, sizeof(ret));
	return ret;
}

static inline void bch_opts_apply(struct bch_opts *dst, struct bch_opts src)
{
#define BCH_OPT(_name, ...)			\
	if (src._name >= 0)						\
		dst->_name = src._name;

	BCH_OPTS()
#undef BCH_OPT
}

#define opt_defined(_opt)		((_opt) >= 0)

void bch_opt_set(struct bch_opts *, enum bch_opt_id, u64);
struct bch_opts bch_sb_opts(struct bch_sb *);

int bch_parse_mount_opts(struct bch_opts *, char *);
enum bch_opt_id bch_parse_sysfs_opt(const char *, const char *, u64 *);

ssize_t bch_opt_show(struct bch_opts *, const char *, char *, size_t);

#endif /* _BCACHE_OPTS_H */