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