bcache: add sysfs file to display feature sets information of cache set

The following three sysfs files are created to display according feature
set information of bcache:
	/sys/fs/bcache/<cache set UUID>/internal/feature_compat
	/sys/fs/bcache/<cache set UUID>/internal/feature_ro_compat
	/sys/fs/bcache/<cache set UUID>/internal/feature_incompat
is added by this patch, to display feature sets information of the cache
set.

Now only an incompat feature 'large_bucket' added in bcache, the sysfs
file content is:
        [large_bucket]
string large_bucket means the running bcache drive supports incompat
feature 'large_bucket', the wrapping [] means the 'large_bucket' feature
is currently enabled on this cache set.

This patch is ready to display compat and ro_compat features, in future
once bcache code implements such feature sets, the according feature
strings will be displayed in their sysfs files too.

Signed-off-by: Coly Li <colyli@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Coly Li 2020-07-25 20:00:36 +08:00 committed by Jens Axboe
parent ffa4703275
commit 092bd54d69
4 changed files with 73 additions and 1 deletions

View File

@ -4,4 +4,4 @@ obj-$(CONFIG_BCACHE) += bcache.o
bcache-y := alloc.o bset.o btree.o closure.o debug.o extents.o\ bcache-y := alloc.o bset.o btree.o closure.o debug.o extents.o\
io.o journal.o movinggc.o request.o stats.o super.o sysfs.o trace.o\ io.o journal.o movinggc.o request.o stats.o super.o sysfs.o trace.o\
util.o writeback.o util.o writeback.o features.o

View File

@ -8,6 +8,7 @@
*/ */
#include <linux/bcache.h> #include <linux/bcache.h>
#include "bcache.h" #include "bcache.h"
#include "features.h"
struct feature { struct feature {
int compat; int compat;
@ -20,3 +21,55 @@ static struct feature feature_list[] = {
"large_bucket"}, "large_bucket"},
{0, 0, 0 }, {0, 0, 0 },
}; };
#define compose_feature_string(type) \
({ \
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(&c->sb, f->mask)) { \
if (first) { \
out += snprintf(out, buf + size - out, \
"["); \
} else { \
out += snprintf(out, buf + size - out, \
" ["); \
} \
} else if (!first) { \
out += snprintf(out, buf + size - out, " "); \
} \
\
out += snprintf(out, buf + size - out, "%s", f->string);\
\
if (BCH_HAS_ ## type ## _FEATURE(&c->sb, f->mask)) \
out += snprintf(out, buf + size - out, "]"); \
\
first = false; \
} \
if (!first) \
out += snprintf(out, buf + size - out, "\n"); \
})
int bch_print_cache_set_feature_compat(struct cache_set *c, char *buf, int size)
{
char *out = buf;
compose_feature_string(COMPAT);
return out - buf;
}
int bch_print_cache_set_feature_ro_compat(struct cache_set *c, char *buf, int size)
{
char *out = buf;
compose_feature_string(RO_COMPAT);
return out - buf;
}
int bch_print_cache_set_feature_incompat(struct cache_set *c, char *buf, int size)
{
char *out = buf;
compose_feature_string(INCOMPAT);
return out - buf;
}

View File

@ -78,4 +78,9 @@ static inline void bch_clear_feature_##name(struct cache_sb *sb) \
} }
BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LARGE_BUCKET); BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LARGE_BUCKET);
int bch_print_cache_set_feature_compat(struct cache_set *c, char *buf, int size);
int bch_print_cache_set_feature_ro_compat(struct cache_set *c, char *buf, int size);
int bch_print_cache_set_feature_incompat(struct cache_set *c, char *buf, int size);
#endif #endif

View File

@ -11,6 +11,7 @@
#include "btree.h" #include "btree.h"
#include "request.h" #include "request.h"
#include "writeback.h" #include "writeback.h"
#include "features.h"
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/sort.h> #include <linux/sort.h>
@ -88,6 +89,9 @@ read_attribute(btree_used_percent);
read_attribute(average_key_size); read_attribute(average_key_size);
read_attribute(dirty_data); read_attribute(dirty_data);
read_attribute(bset_tree_stats); read_attribute(bset_tree_stats);
read_attribute(feature_compat);
read_attribute(feature_ro_compat);
read_attribute(feature_incompat);
read_attribute(state); read_attribute(state);
read_attribute(cache_read_races); read_attribute(cache_read_races);
@ -779,6 +783,13 @@ SHOW(__bch_cache_set)
if (attr == &sysfs_bset_tree_stats) if (attr == &sysfs_bset_tree_stats)
return bch_bset_print_stats(c, buf); return bch_bset_print_stats(c, buf);
if (attr == &sysfs_feature_compat)
return bch_print_cache_set_feature_compat(c, buf, PAGE_SIZE);
if (attr == &sysfs_feature_ro_compat)
return bch_print_cache_set_feature_ro_compat(c, buf, PAGE_SIZE);
if (attr == &sysfs_feature_incompat)
return bch_print_cache_set_feature_incompat(c, buf, PAGE_SIZE);
return 0; return 0;
} }
SHOW_LOCKED(bch_cache_set) SHOW_LOCKED(bch_cache_set)
@ -987,6 +998,9 @@ static struct attribute *bch_cache_set_internal_files[] = {
&sysfs_io_disable, &sysfs_io_disable,
&sysfs_cutoff_writeback, &sysfs_cutoff_writeback,
&sysfs_cutoff_writeback_sync, &sysfs_cutoff_writeback_sync,
&sysfs_feature_compat,
&sysfs_feature_ro_compat,
&sysfs_feature_incompat,
NULL NULL
}; };
KTYPE(bch_cache_set_internal); KTYPE(bch_cache_set_internal);