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) \ 34static 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} \ 41static inline void bch_set_feature_##name(struct cache_sb *sb) \ 42{ \ 43 (sb)->feature_compat |= \ 44 BCH##_FEATURE_COMPAT_##flagname; \ 45} \ 46static 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) \ 53static 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} \ 60static inline void bch_set_feature_##name(struct cache_sb *sb) \ 61{ \ 62 (sb)->feature_ro_compat |= \ 63 BCH##_FEATURE_RO_COMPAT_##flagname; \ 64} \ 65static 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) \ 72static 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} \ 79static inline void bch_set_feature_##name(struct cache_sb *sb) \ 80{ \ 81 (sb)->feature_incompat |= \ 82 BCH##_FEATURE_INCOMPAT_##flagname; \ 83} \ 84static inline void bch_clear_feature_##name(struct cache_sb *sb) \ 85{ \ 86 (sb)->feature_incompat &= \ 87 ~BCH##_FEATURE_INCOMPAT_##flagname; \ 88} 89 90BCH_FEATURE_INCOMPAT_FUNCS(obso_large_bucket, OBSO_LARGE_BUCKET); 91BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LOG_LARGE_BUCKET_SIZE); 92 93static inline bool bch_has_unknown_compat_features(struct cache_sb *sb) 94{ 95 return ((sb->feature_compat & ~BCH_FEATURE_COMPAT_SUPP) != 0); 96} 97 98static 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 103static inline bool bch_has_unknown_incompat_features(struct cache_sb *sb) 104{ 105 return ((sb->feature_incompat & ~BCH_FEATURE_INCOMPAT_SUPP) != 0); 106} 107 108int bch_print_cache_set_feature_compat(struct cache_set *c, char *buf, int size); 109int bch_print_cache_set_feature_ro_compat(struct cache_set *c, char *buf, int size); 110int bch_print_cache_set_feature_incompat(struct cache_set *c, char *buf, int size); 111 112#endif 113