File 0011-bcache-tools-add-print_cache_set_supported_feature_s.patch of Package bcache-tools.17273
From 047c4c4abdb49140ecf91d5e17624f2bf2535a69 Mon Sep 17 00:00:00 2001
From: Coly Li <colyli@suse.de>
Date: Mon, 17 Aug 2020 19:23:10 +0800
Subject: [PATCH 11/17] bcache-tools: add
print_cache_set_supported_feature_sets() in lib.c
Git-commit: 047c4c4abdb49140ecf91d5e17624f2bf2535a69
Patch-mainline: bcache-tools-1.1
References: jsc#SLE-9807
print_cache_set_supported_feature_sets() is used to print out feature
set strings for a specified cache device super block. It can be used
when make a bcache cache device, or show a super block information of
a bcache cache device.
Signed-off-by: Coly Li <colyli@suse.de>
---
bcache-super-show.c | 2 ++
bcache.c | 15 +++++++++++---
features.c | 50 +++++++++++++++++++++++++++++++++++++++++++++
features.h | 8 ++++++++
lib.c | 20 +++++++++++-------
lib.h | 4 ++++
6 files changed, 89 insertions(+), 10 deletions(-)
create mode 100644 features.h
diff --git a/bcache-super-show.c b/bcache-super-show.c
index 883410f..cc36029 100644
--- a/bcache-super-show.c
+++ b/bcache-super-show.c
@@ -134,12 +134,14 @@ int main(int argc, char **argv)
// These are handled the same by the kernel
case BCACHE_SB_VERSION_CDEV:
case BCACHE_SB_VERSION_CDEV_WITH_UUID:
+ case BCACHE_SB_VERSION_CDEV_WITH_FEATURES:
printf(" [cache device]\n");
break;
// The second adds data offset support
case BCACHE_SB_VERSION_BDEV:
case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
+ case BCACHE_SB_VERSION_BDEV_WITH_FEATURES:
printf(" [backing device]\n");
break;
diff --git a/bcache.c b/bcache.c
index b866271..50e3a88 100644
--- a/bcache.c
+++ b/bcache.c
@@ -18,6 +18,7 @@
#include "list.h"
#include <limits.h>
+#include "features.h"
#define BCACHE_TOOLS_VERSION "1.1"
@@ -203,11 +204,13 @@ int show_bdevs_detail(void)
// These are handled the same by the kernel
case BCACHE_SB_VERSION_CDEV:
case BCACHE_SB_VERSION_CDEV_WITH_UUID:
+ case BCACHE_SB_VERSION_CDEV_WITH_FEATURES:
printf(" (cache)");
break;
// The second adds data offset supporet
case BCACHE_SB_VERSION_BDEV:
case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
+ case BCACHE_SB_VERSION_BDEV_WITH_FEATURES:
printf(" (data)");
break;
default:
@@ -257,12 +260,14 @@ int show_bdevs(void)
// These are handled the same by the kernel
case BCACHE_SB_VERSION_CDEV:
case BCACHE_SB_VERSION_CDEV_WITH_UUID:
+ case BCACHE_SB_VERSION_CDEV_WITH_FEATURES:
printf(" (cache)");
break;
// The second adds data offset supporet
case BCACHE_SB_VERSION_BDEV:
case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
+ case BCACHE_SB_VERSION_BDEV_WITH_FEATURES:
printf(" (data)");
break;
@@ -304,7 +309,9 @@ int detail_single(char *devname)
fprintf(stderr, "Failed to detail device\n");
return ret;
}
- if (type == BCACHE_SB_VERSION_BDEV) {
+ if (type == BCACHE_SB_VERSION_BDEV ||
+ type == BCACHE_SB_VERSION_BDEV_WITH_OFFSET ||
+ type == BCACHE_SB_VERSION_BDEV_WITH_FEATURES) {
printf("sb.magic\t\t%s\n", bd.base.magic);
printf("sb.first_sector\t\t%" PRIu64 "\n",
bd.base.first_sector);
@@ -362,14 +369,16 @@ int detail_single(char *devname)
putchar('\n');
printf("cset.uuid\t\t%s\n", bd.base.cset);
- } else if (type == BCACHE_SB_VERSION_CDEV
- || type == BCACHE_SB_VERSION_CDEV_WITH_UUID) {
+ } else if (type == BCACHE_SB_VERSION_CDEV ||
+ type == BCACHE_SB_VERSION_CDEV_WITH_UUID ||
+ type == BCACHE_SB_VERSION_CDEV_WITH_FEATURES) {
printf("sb.magic\t\t%s\n", cd.base.magic);
printf("sb.first_sector\t\t%" PRIu64 "\n",
cd.base.first_sector);
printf("sb.csum\t\t\t%" PRIX64 "\n", cd.base.csum);
printf("sb.version\t\t%" PRIu64, cd.base.version);
printf(" [cache device]\n");
+ print_cache_set_supported_feature_sets(&cd.base.sb);
putchar('\n');
printf("dev.label\t\t");
if (*cd.base.label)
diff --git a/features.c b/features.c
index df15862..181e348 100644
--- a/features.c
+++ b/features.c
@@ -7,7 +7,9 @@
*/
#include <stdbool.h>
#include <stdint.h>
+#include <stdio.h>
#include <sys/types.h>
+#include <string.h>
#include "bcache.h"
@@ -22,3 +24,51 @@ static struct feature feature_list[] = {
"large_bucket"},
{0, 0, 0 },
};
+
+#define compose_feature_string(type, header) \
+({ \
+ struct feature *f; \
+ bool first = true; \
+ \
+ for (f = &feature_list[0]; f->compat != 0; f++) { \
+ if (f->compat != BCH_FEATURE_ ## type) \
+ continue; \
+ if (!(BCH_HAS_ ## type ## _FEATURE(sb, f->mask))) \
+ continue; \
+ \
+ if (first) { \
+ out += snprintf(out, buf + size - out, \
+ "%s:\t", (header)); \
+ first = false; \
+ } else { \
+ out += snprintf(out, buf + size - out, " "); \
+ } \
+ \
+ out += snprintf(out, buf + size - out, "%s", f->string);\
+ \
+ } \
+ if (!first) \
+ out += snprintf(out, buf + size - out, "\n"); \
+})
+
+void print_cache_set_supported_feature_sets(struct cache_sb *sb)
+{
+ char buf[4096];
+ char *out;
+ int size = sizeof(buf) - 1;
+
+ out = buf;
+ memset(buf, 0, sizeof(buf));
+ compose_feature_string(COMPAT, "sb.feature_compat");
+ printf("%s", buf);
+
+ out = buf;
+ memset(buf, 0, sizeof(buf));
+ compose_feature_string(RO_COMPAT, "sb.feature_ro_compat");
+ printf("%s", buf);
+
+ out = buf;
+ memset(buf, 0, sizeof(buf));
+ compose_feature_string(INCOMPAT, "sb.feature_incompat");
+ printf("%s", buf);
+}
diff --git a/features.h b/features.h
new file mode 100644
index 0000000..028b774
--- /dev/null
+++ b/features.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _BCACHE_FEATURES_H
+#define _BCACHE_FEATURES_H
+
+void print_cache_set_supported_feature_sets(struct cache_sb *sb);
+
+#endif
diff --git a/lib.c b/lib.c
index efabeb1..29172f5 100644
--- a/lib.c
+++ b/lib.c
@@ -192,11 +192,13 @@ int get_cachedev_state(char *cset_id, char *state)
int get_state(struct dev *dev, char *state)
{
- if (dev->version == BCACHE_SB_VERSION_CDEV
- || dev->version == BCACHE_SB_VERSION_CDEV_WITH_UUID)
+ if (dev->version == BCACHE_SB_VERSION_CDEV ||
+ dev->version == BCACHE_SB_VERSION_CDEV_WITH_UUID ||
+ dev->version == BCACHE_SB_VERSION_CDEV_WITH_FEATURES)
return get_cachedev_state(dev->cset, state);
- else if (dev->version == BCACHE_SB_VERSION_BDEV
- || dev->version == BCACHE_SB_VERSION_BDEV_WITH_OFFSET)
+ else if (dev->version == BCACHE_SB_VERSION_BDEV ||
+ dev->version == BCACHE_SB_VERSION_BDEV_WITH_OFFSET ||
+ dev->version == BCACHE_SB_VERSION_BDEV_WITH_FEATURES)
return get_backdev_state(dev->name, state);
else
return 1;
@@ -291,6 +293,7 @@ int detail_base(char *devname, struct cache_sb sb, struct dev *base)
{
int ret;
+ base->sb = sb;
strcpy(base->name, devname);
base->magic = "ok";
base->first_sector = SB_SECTOR;
@@ -440,13 +443,16 @@ int detail_dev(char *devname, struct bdev *bd, struct cdev *cd, int *type)
}
*type = sb.version;
- if (sb.version == BCACHE_SB_VERSION_BDEV) {
+ if (sb.version == BCACHE_SB_VERSION_BDEV ||
+ sb.version == BCACHE_SB_VERSION_BDEV_WITH_OFFSET ||
+ sb.version == BCACHE_SB_VERSION_BDEV_WITH_FEATURES) {
detail_base(devname, sb, &bd->base);
bd->first_sector = BDEV_DATA_START_DEFAULT;
bd->cache_mode = BDEV_CACHE_MODE(&sb);
bd->cache_state = BDEV_STATE(&sb);
- } else if (sb.version == BCACHE_SB_VERSION_CDEV
- || sb.version == BCACHE_SB_VERSION_CDEV_WITH_UUID) {
+ } else if (sb.version == BCACHE_SB_VERSION_CDEV ||
+ sb.version == BCACHE_SB_VERSION_CDEV_WITH_UUID ||
+ sb.version == BCACHE_SB_VERSION_CDEV_WITH_FEATURES) {
detail_base(devname, sb, &cd->base);
cd->first_sector = sb.bucket_size * sb.first_bucket;
cd->cache_sectors =
diff --git a/lib.h b/lib.h
index 1dd2bfe..9b5ed02 100644
--- a/lib.h
+++ b/lib.h
@@ -4,6 +4,7 @@
#include "list.h"
struct dev {
+ struct cache_sb sb;
char name[40];
char *magic;
uint64_t first_sector;
@@ -17,6 +18,9 @@ struct dev {
char state[40];
char bname[40];
char attachuuid[40];
+ uint64_t feature_compat;
+ uint64_t feature_ro_compat;
+ uint64_t feature_incompat;
struct list_head dev_list;
};
--
2.26.2