summaryrefslogtreecommitdiff
path: root/drivers/md/bcache/opts.h
blob: 70df232c589209c50a66138f02031c8057436a30 (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
#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_cache_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 cache_set_alloc() as a whole struct, and then
 * only apply the options from that struct that are defined.
 */

extern const char * const bch_bool_opt[];
extern const char * const bch_uint_opt[];

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

#define CACHE_SET_VISIBLE_OPTS()				\
	CACHE_SET_OPT(verbose_recovery,				\
		      bch_bool_opt, 0, 2,			\
		      NO_SB_OPT, false)				\
	CACHE_SET_OPT(posix_acl,				\
		      bch_bool_opt, 0, 2,			\
		      NO_SB_OPT, false)				\
	CACHE_SET_OPT(journal_flush_disabled,			\
		      bch_bool_opt, 0, 2,			\
		      NO_SB_OPT, true)				\
	CACHE_SET_OPT(nofsck,					\
		      bch_bool_opt, 0, 2,			\
		      NO_SB_OPT, true)				\
	CACHE_SET_OPT(fix_errors,				\
		      bch_bool_opt, 0, 2,			\
		      NO_SB_OPT, true)				\
	CACHE_SET_OPT(nochanges,				\
		      bch_bool_opt, 0, 2,			\
		      NO_SB_OPT, 0)				\
	CACHE_SET_OPT(noreplay,					\
		      bch_bool_opt, 0, 2,			\
		      NO_SB_OPT, 0)				\
	CACHE_SET_OPT(norecovery,				\
		      bch_bool_opt, 0, 2,			\
		      NO_SB_OPT, 0)				\
	CACHE_SET_SB_OPTS()

#define CACHE_SET_OPTS()					\
	CACHE_SET_OPT(read_only,				\
		      bch_bool_opt, 0, 2,			\
		      NO_SB_OPT, 0)				\
	CACHE_SET_VISIBLE_OPTS()

struct cache_set_opts {
#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm)\
	s8 _name;

	CACHE_SET_OPTS()
#undef CACHE_SET_OPT
};

static inline struct cache_set_opts cache_set_opts_empty(void)
{
	struct cache_set_opts ret;

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

/*
 * Initial options from superblock - here we don't want any options undefined,
 * any options the superblock doesn't specify are set to 0:
 */
static inline struct cache_set_opts cache_superblock_opts(struct cache_sb *sb)
{
	return (struct cache_set_opts) {
#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm)\
		._name = _sb_opt##_BITS ? _sb_opt(sb) : 0,

	CACHE_SET_OPTS()
#undef CACHE_SET_OPT
	};
}

static inline void cache_set_opts_apply(struct cache_set_opts *dst,
					struct cache_set_opts src)
{
#define CACHE_SET_OPT(_name, _choices, _min, _max, _sb_opt, _perm)\
	BUILD_BUG_ON(_max > S8_MAX);				\
	if (src._name >= 0)					\
		dst->_name = src._name;

	CACHE_SET_OPTS()
#undef CACHE_SET_OPT
}

int bch_parse_options(struct cache_set_opts *, int, char *);

#endif /* _BCACHE_OPTS_H */