1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Feature set bits and string conversion. 4 * Inspired by ext4's features compat/incompat/ro_compat related code. 5 * 6 * Copyright 2020 Coly Li <colyli@suse.de> 7 * 8 */ 9 #include <linux/bcache.h> 10 #include "bcache.h" 11 #include "features.h" 12 13 struct feature { 14 int compat; 15 unsigned int mask; 16 const char *string; 17 }; 18 19 static struct feature feature_list[] = { 20 {BCH_FEATURE_INCOMPAT, BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE, 21 "large_bucket"}, 22 {0, 0, 0 }, 23 }; 24 25 #define compose_feature_string(type) \ 26 ({ \ 27 struct feature *f; \ 28 bool first = true; \ 29 \ 30 for (f = &feature_list[0]; f->compat != 0; f++) { \ 31 if (f->compat != BCH_FEATURE_ ## type) \ 32 continue; \ 33 if (BCH_HAS_ ## type ## _FEATURE(&c->cache->sb, f->mask)) { \ 34 if (first) { \ 35 out += snprintf(out, buf + size - out, \ 36 "["); \ 37 } else { \ 38 out += snprintf(out, buf + size - out, \ 39 " ["); \ 40 } \ 41 } else if (!first) { \ 42 out += snprintf(out, buf + size - out, " "); \ 43 } \ 44 \ 45 out += snprintf(out, buf + size - out, "%s", f->string);\ 46 \ 47 if (BCH_HAS_ ## type ## _FEATURE(&c->cache->sb, f->mask)) \ 48 out += snprintf(out, buf + size - out, "]"); \ 49 \ 50 first = false; \ 51 } \ 52 if (!first) \ 53 out += snprintf(out, buf + size - out, "\n"); \ 54 }) 55 56 int bch_print_cache_set_feature_compat(struct cache_set *c, char *buf, int size) 57 { 58 char *out = buf; 59 compose_feature_string(COMPAT); 60 return out - buf; 61 } 62 63 int bch_print_cache_set_feature_ro_compat(struct cache_set *c, char *buf, int size) 64 { 65 char *out = buf; 66 compose_feature_string(RO_COMPAT); 67 return out - buf; 68 } 69 70 int bch_print_cache_set_feature_incompat(struct cache_set *c, char *buf, int size) 71 { 72 char *out = buf; 73 compose_feature_string(INCOMPAT); 74 return out - buf; 75 } 76