1 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 #ifndef _BCACHE_FEATURES_H 3 #define _BCACHE_FEATURES_H 4 5 #include <linux/bcache.h> 6 #include <linux/kernel.h> 7 #include <linux/types.h> 8 9 #define BCH_FEATURE_COMPAT 0 10 #define BCH_FEATURE_RO_COMPAT 1 11 #define BCH_FEATURE_INCOMPAT 2 12 #define BCH_FEATURE_TYPE_MASK 0x03 13 14 /* Feature set definition */ 15 /* Incompat feature set */ 16 /* 32bit bucket size, obsoleted */ 17 #define BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET 0x0001 18 /* real bucket size is (1 << bucket_size) */ 19 #define BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE 0x0002 20 21 #define BCH_FEATURE_COMPAT_SUPP 0 22 #define BCH_FEATURE_RO_COMPAT_SUPP 0 23 #define BCH_FEATURE_INCOMPAT_SUPP (BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET| \ 24 BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE) 25 26 #define BCH_HAS_COMPAT_FEATURE(sb, mask) \ 27 ((sb)->feature_compat & (mask)) 28 #define BCH_HAS_RO_COMPAT_FEATURE(sb, mask) \ 29 ((sb)->feature_ro_compat & (mask)) 30 #define BCH_HAS_INCOMPAT_FEATURE(sb, mask) \ 31 ((sb)->feature_incompat & (mask)) 32 33 #define BCH_FEATURE_COMPAT_FUNCS(name, flagname) \ 34 static inline int bch_has_feature_##name(struct cache_sb *sb) \ 35 { \ 36 if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \ 37 return 0; \ 38 return (((sb)->feature_compat & \ 39 BCH##_FEATURE_COMPAT_##flagname) != 0); \ 40 } \ 41 static inline void bch_set_feature_##name(struct cache_sb *sb) \ 42 { \ 43 (sb)->feature_compat |= \ 44 BCH##_FEATURE_COMPAT_##flagname; \ 45 } \ 46 static inline void bch_clear_feature_##name(struct cache_sb *sb) \ 47 { \ 48 (sb)->feature_compat &= \ 49 ~BCH##_FEATURE_COMPAT_##flagname; \ 50 } 51 52 #define BCH_FEATURE_RO_COMPAT_FUNCS(name, flagname) \ 53 static inline int bch_has_feature_##name(struct cache_sb *sb) \ 54 { \ 55 if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \ 56 return 0; \ 57 return (((sb)->feature_ro_compat & \ 58 BCH##_FEATURE_RO_COMPAT_##flagname) != 0); \ 59 } \ 60 static inline void bch_set_feature_##name(struct cache_sb *sb) \ 61 { \ 62 (sb)->feature_ro_compat |= \ 63 BCH##_FEATURE_RO_COMPAT_##flagname; \ 64 } \ 65 static inline void bch_clear_feature_##name(struct cache_sb *sb) \ 66 { \ 67 (sb)->feature_ro_compat &= \ 68 ~BCH##_FEATURE_RO_COMPAT_##flagname; \ 69 } 70 71 #define BCH_FEATURE_INCOMPAT_FUNCS(name, flagname) \ 72 static inline int bch_has_feature_##name(struct cache_sb *sb) \ 73 { \ 74 if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \ 75 return 0; \ 76 return (((sb)->feature_incompat & \ 77 BCH##_FEATURE_INCOMPAT_##flagname) != 0); \ 78 } \ 79 static inline void bch_set_feature_##name(struct cache_sb *sb) \ 80 { \ 81 (sb)->feature_incompat |= \ 82 BCH##_FEATURE_INCOMPAT_##flagname; \ 83 } \ 84 static inline void bch_clear_feature_##name(struct cache_sb *sb) \ 85 { \ 86 (sb)->feature_incompat &= \ 87 ~BCH##_FEATURE_INCOMPAT_##flagname; \ 88 } 89 90 BCH_FEATURE_INCOMPAT_FUNCS(obso_large_bucket, OBSO_LARGE_BUCKET); 91 BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LOG_LARGE_BUCKET_SIZE); 92 93 static inline bool bch_has_unknown_compat_features(struct cache_sb *sb) 94 { 95 return ((sb->feature_compat & ~BCH_FEATURE_COMPAT_SUPP) != 0); 96 } 97 98 static inline bool bch_has_unknown_ro_compat_features(struct cache_sb *sb) 99 { 100 return ((sb->feature_ro_compat & ~BCH_FEATURE_RO_COMPAT_SUPP) != 0); 101 } 102 103 static inline bool bch_has_unknown_incompat_features(struct cache_sb *sb) 104 { 105 return ((sb->feature_incompat & ~BCH_FEATURE_INCOMPAT_SUPP) != 0); 106 } 107 108 int bch_print_cache_set_feature_compat(struct cache_set *c, char *buf, int size); 109 int bch_print_cache_set_feature_ro_compat(struct cache_set *c, char *buf, int size); 110 int bch_print_cache_set_feature_incompat(struct cache_set *c, char *buf, int size); 111 112 #endif 113