0001
0002 #ifndef _BCACHE_FEATURES_H
0003 #define _BCACHE_FEATURES_H
0004
0005 #include <linux/kernel.h>
0006 #include <linux/types.h>
0007
0008 #include "bcache_ondisk.h"
0009
0010 #define BCH_FEATURE_COMPAT 0
0011 #define BCH_FEATURE_RO_COMPAT 1
0012 #define BCH_FEATURE_INCOMPAT 2
0013 #define BCH_FEATURE_TYPE_MASK 0x03
0014
0015
0016
0017
0018 #define BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET 0x0001
0019
0020 #define BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE 0x0002
0021
0022 #define BCH_FEATURE_COMPAT_SUPP 0
0023 #define BCH_FEATURE_RO_COMPAT_SUPP 0
0024 #define BCH_FEATURE_INCOMPAT_SUPP (BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET| \
0025 BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE)
0026
0027 #define BCH_HAS_COMPAT_FEATURE(sb, mask) \
0028 ((sb)->feature_compat & (mask))
0029 #define BCH_HAS_RO_COMPAT_FEATURE(sb, mask) \
0030 ((sb)->feature_ro_compat & (mask))
0031 #define BCH_HAS_INCOMPAT_FEATURE(sb, mask) \
0032 ((sb)->feature_incompat & (mask))
0033
0034 #define BCH_FEATURE_COMPAT_FUNCS(name, flagname) \
0035 static inline int bch_has_feature_##name(struct cache_sb *sb) \
0036 { \
0037 if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \
0038 return 0; \
0039 return (((sb)->feature_compat & \
0040 BCH##_FEATURE_COMPAT_##flagname) != 0); \
0041 } \
0042 static inline void bch_set_feature_##name(struct cache_sb *sb) \
0043 { \
0044 (sb)->feature_compat |= \
0045 BCH##_FEATURE_COMPAT_##flagname; \
0046 } \
0047 static inline void bch_clear_feature_##name(struct cache_sb *sb) \
0048 { \
0049 (sb)->feature_compat &= \
0050 ~BCH##_FEATURE_COMPAT_##flagname; \
0051 }
0052
0053 #define BCH_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
0054 static inline int bch_has_feature_##name(struct cache_sb *sb) \
0055 { \
0056 if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \
0057 return 0; \
0058 return (((sb)->feature_ro_compat & \
0059 BCH##_FEATURE_RO_COMPAT_##flagname) != 0); \
0060 } \
0061 static inline void bch_set_feature_##name(struct cache_sb *sb) \
0062 { \
0063 (sb)->feature_ro_compat |= \
0064 BCH##_FEATURE_RO_COMPAT_##flagname; \
0065 } \
0066 static inline void bch_clear_feature_##name(struct cache_sb *sb) \
0067 { \
0068 (sb)->feature_ro_compat &= \
0069 ~BCH##_FEATURE_RO_COMPAT_##flagname; \
0070 }
0071
0072 #define BCH_FEATURE_INCOMPAT_FUNCS(name, flagname) \
0073 static inline int bch_has_feature_##name(struct cache_sb *sb) \
0074 { \
0075 if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \
0076 return 0; \
0077 return (((sb)->feature_incompat & \
0078 BCH##_FEATURE_INCOMPAT_##flagname) != 0); \
0079 } \
0080 static inline void bch_set_feature_##name(struct cache_sb *sb) \
0081 { \
0082 (sb)->feature_incompat |= \
0083 BCH##_FEATURE_INCOMPAT_##flagname; \
0084 } \
0085 static inline void bch_clear_feature_##name(struct cache_sb *sb) \
0086 { \
0087 (sb)->feature_incompat &= \
0088 ~BCH##_FEATURE_INCOMPAT_##flagname; \
0089 }
0090
0091 BCH_FEATURE_INCOMPAT_FUNCS(obso_large_bucket, OBSO_LARGE_BUCKET);
0092 BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LOG_LARGE_BUCKET_SIZE);
0093
0094 static inline bool bch_has_unknown_compat_features(struct cache_sb *sb)
0095 {
0096 return ((sb->feature_compat & ~BCH_FEATURE_COMPAT_SUPP) != 0);
0097 }
0098
0099 static inline bool bch_has_unknown_ro_compat_features(struct cache_sb *sb)
0100 {
0101 return ((sb->feature_ro_compat & ~BCH_FEATURE_RO_COMPAT_SUPP) != 0);
0102 }
0103
0104 static inline bool bch_has_unknown_incompat_features(struct cache_sb *sb)
0105 {
0106 return ((sb->feature_incompat & ~BCH_FEATURE_INCOMPAT_SUPP) != 0);
0107 }
0108
0109 int bch_print_cache_set_feature_compat(struct cache_set *c, char *buf, int size);
0110 int bch_print_cache_set_feature_ro_compat(struct cache_set *c, char *buf, int size);
0111 int bch_print_cache_set_feature_incompat(struct cache_set *c, char *buf, int size);
0112
0113 #endif