xref: /openbmc/linux/drivers/md/bcache/features.h (revision cf2197ca)
1d721a43fSColy Li /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2d721a43fSColy Li #ifndef _BCACHE_FEATURES_H
3d721a43fSColy Li #define _BCACHE_FEATURES_H
4d721a43fSColy Li 
5d721a43fSColy Li #include <linux/kernel.h>
6d721a43fSColy Li #include <linux/types.h>
7d721a43fSColy Li 
8*cf2197caSColy Li #include "bcache_ondisk.h"
9*cf2197caSColy Li 
10d721a43fSColy Li #define BCH_FEATURE_COMPAT		0
11d721a43fSColy Li #define BCH_FEATURE_RO_COMPAT		1
12d721a43fSColy Li #define BCH_FEATURE_INCOMPAT		2
13d721a43fSColy Li #define BCH_FEATURE_TYPE_MASK		0x03
14d721a43fSColy Li 
15ffa47032SColy Li /* Feature set definition */
16ffa47032SColy Li /* Incompat feature set */
17b16671e8SColy Li /* 32bit bucket size, obsoleted */
18b16671e8SColy Li #define BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET		0x0001
19b16671e8SColy Li /* real bucket size is (1 << bucket_size) */
20b16671e8SColy Li #define BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE	0x0002
21ffa47032SColy Li 
22f7b4943dSColy Li #define BCH_FEATURE_COMPAT_SUPP		0
23f7b4943dSColy Li #define BCH_FEATURE_RO_COMPAT_SUPP	0
24b16671e8SColy Li #define BCH_FEATURE_INCOMPAT_SUPP	(BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET| \
25b16671e8SColy Li 					 BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE)
26d721a43fSColy Li 
27d721a43fSColy Li #define BCH_HAS_COMPAT_FEATURE(sb, mask) \
28d721a43fSColy Li 		((sb)->feature_compat & (mask))
29d721a43fSColy Li #define BCH_HAS_RO_COMPAT_FEATURE(sb, mask) \
30d721a43fSColy Li 		((sb)->feature_ro_compat & (mask))
31d721a43fSColy Li #define BCH_HAS_INCOMPAT_FEATURE(sb, mask) \
32d721a43fSColy Li 		((sb)->feature_incompat & (mask))
33d721a43fSColy Li 
34d721a43fSColy Li #define BCH_FEATURE_COMPAT_FUNCS(name, flagname) \
35d721a43fSColy Li static inline int bch_has_feature_##name(struct cache_sb *sb) \
36d721a43fSColy Li { \
370df28cadSColy Li 	if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \
380df28cadSColy Li 		return 0; \
39d721a43fSColy Li 	return (((sb)->feature_compat & \
40d721a43fSColy Li 		BCH##_FEATURE_COMPAT_##flagname) != 0); \
41d721a43fSColy Li } \
42d721a43fSColy Li static inline void bch_set_feature_##name(struct cache_sb *sb) \
43d721a43fSColy Li { \
44d721a43fSColy Li 	(sb)->feature_compat |= \
45d721a43fSColy Li 		BCH##_FEATURE_COMPAT_##flagname; \
46d721a43fSColy Li } \
47d721a43fSColy Li static inline void bch_clear_feature_##name(struct cache_sb *sb) \
48d721a43fSColy Li { \
49d721a43fSColy Li 	(sb)->feature_compat &= \
50d721a43fSColy Li 		~BCH##_FEATURE_COMPAT_##flagname; \
51d721a43fSColy Li }
52d721a43fSColy Li 
53d721a43fSColy Li #define BCH_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
54d721a43fSColy Li static inline int bch_has_feature_##name(struct cache_sb *sb) \
55d721a43fSColy Li { \
560df28cadSColy Li 	if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \
570df28cadSColy Li 		return 0; \
58d721a43fSColy Li 	return (((sb)->feature_ro_compat & \
59d721a43fSColy Li 		BCH##_FEATURE_RO_COMPAT_##flagname) != 0); \
60d721a43fSColy Li } \
61d721a43fSColy Li static inline void bch_set_feature_##name(struct cache_sb *sb) \
62d721a43fSColy Li { \
63d721a43fSColy Li 	(sb)->feature_ro_compat |= \
64d721a43fSColy Li 		BCH##_FEATURE_RO_COMPAT_##flagname; \
65d721a43fSColy Li } \
66d721a43fSColy Li static inline void bch_clear_feature_##name(struct cache_sb *sb) \
67d721a43fSColy Li { \
68d721a43fSColy Li 	(sb)->feature_ro_compat &= \
69d721a43fSColy Li 		~BCH##_FEATURE_RO_COMPAT_##flagname; \
70d721a43fSColy Li }
71d721a43fSColy Li 
72d721a43fSColy Li #define BCH_FEATURE_INCOMPAT_FUNCS(name, flagname) \
73d721a43fSColy Li static inline int bch_has_feature_##name(struct cache_sb *sb) \
74d721a43fSColy Li { \
750df28cadSColy Li 	if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \
760df28cadSColy Li 		return 0; \
77d721a43fSColy Li 	return (((sb)->feature_incompat & \
78d721a43fSColy Li 		BCH##_FEATURE_INCOMPAT_##flagname) != 0); \
79d721a43fSColy Li } \
80d721a43fSColy Li static inline void bch_set_feature_##name(struct cache_sb *sb) \
81d721a43fSColy Li { \
82d721a43fSColy Li 	(sb)->feature_incompat |= \
83d721a43fSColy Li 		BCH##_FEATURE_INCOMPAT_##flagname; \
84d721a43fSColy Li } \
85d721a43fSColy Li static inline void bch_clear_feature_##name(struct cache_sb *sb) \
86d721a43fSColy Li { \
87d721a43fSColy Li 	(sb)->feature_incompat &= \
88d721a43fSColy Li 		~BCH##_FEATURE_INCOMPAT_##flagname; \
89d721a43fSColy Li }
90d721a43fSColy Li 
91b16671e8SColy Li BCH_FEATURE_INCOMPAT_FUNCS(obso_large_bucket, OBSO_LARGE_BUCKET);
92b16671e8SColy Li BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LOG_LARGE_BUCKET_SIZE);
93092bd54dSColy Li 
bch_has_unknown_compat_features(struct cache_sb * sb)941dfc0686SColy Li static inline bool bch_has_unknown_compat_features(struct cache_sb *sb)
951dfc0686SColy Li {
961dfc0686SColy Li 	return ((sb->feature_compat & ~BCH_FEATURE_COMPAT_SUPP) != 0);
971dfc0686SColy Li }
981dfc0686SColy Li 
bch_has_unknown_ro_compat_features(struct cache_sb * sb)991dfc0686SColy Li static inline bool bch_has_unknown_ro_compat_features(struct cache_sb *sb)
1001dfc0686SColy Li {
1011dfc0686SColy Li 	return ((sb->feature_ro_compat & ~BCH_FEATURE_RO_COMPAT_SUPP) != 0);
1021dfc0686SColy Li }
1031dfc0686SColy Li 
bch_has_unknown_incompat_features(struct cache_sb * sb)1041dfc0686SColy Li static inline bool bch_has_unknown_incompat_features(struct cache_sb *sb)
1051dfc0686SColy Li {
1061dfc0686SColy Li 	return ((sb->feature_incompat & ~BCH_FEATURE_INCOMPAT_SUPP) != 0);
1071dfc0686SColy Li }
1081dfc0686SColy Li 
109092bd54dSColy Li int bch_print_cache_set_feature_compat(struct cache_set *c, char *buf, int size);
110092bd54dSColy Li int bch_print_cache_set_feature_ro_compat(struct cache_set *c, char *buf, int size);
111092bd54dSColy Li int bch_print_cache_set_feature_incompat(struct cache_set *c, char *buf, int size);
112092bd54dSColy Li 
113d721a43fSColy Li #endif
114