forked from pool/bcache-tools
194 lines
5.6 KiB
Diff
194 lines
5.6 KiB
Diff
|
From 8c063851990a5e82ba1727907994a46201d9e842 Mon Sep 17 00:00:00 2001
|
||
|
From: Coly Li <colyli@suse.de>
|
||
|
Date: Mon, 17 Aug 2020 01:37:17 +0800
|
||
|
Subject: [PATCH 10/17] bcache-tools: add large_bucket incompat feature
|
||
|
Git-commit: 8c063851990a5e82ba1727907994a46201d9e842
|
||
|
Patch-mainline: bcache-tools-1.1
|
||
|
References: jsc#SLE-9807
|
||
|
|
||
|
This feature adds __le16 bucket_size_hi into struct cache_sb_disk, to
|
||
|
permit bucket size to be 32bit width. Current maximum bucket size is
|
||
|
16MB, extend it to 32bits will permit much large bucket size which is
|
||
|
desired by zoned SSD devices (a typical zone size is 256MB).
|
||
|
|
||
|
When setting a bucket size > 16MB, large_bucket feature will be set
|
||
|
automatically and the super block version will also be set to
|
||
|
BCACHE_SB_VERSION_CDEV_WITH_FEATURES.
|
||
|
|
||
|
Signed-off-by: Coly Li <colyli@suse.de>
|
||
|
---
|
||
|
bcache.h | 8 ++++++++
|
||
|
features.c | 2 ++
|
||
|
lib.c | 19 +++++++++++++++++++
|
||
|
lib.h | 1 +
|
||
|
make.c | 18 ++++++++++++------
|
||
|
5 files changed, 42 insertions(+), 6 deletions(-)
|
||
|
|
||
|
diff --git a/bcache.h b/bcache.h
|
||
|
index 9d969e1..6aef9c4 100644
|
||
|
--- a/bcache.h
|
||
|
+++ b/bcache.h
|
||
|
@@ -100,6 +100,7 @@ struct cache_sb_disk {
|
||
|
__le16 keys;
|
||
|
};
|
||
|
__le64 d[SB_JOURNAL_BUCKETS]; /* journal buckets */
|
||
|
+ __le16 bucket_size_hi;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
@@ -210,6 +211,11 @@ uint64_t crc64(const void *data, size_t len);
|
||
|
#define BCH_HAS_INCOMPAT_FEATURE(sb, mask) \
|
||
|
((sb)->feature_incompat & (mask))
|
||
|
|
||
|
+/* Feature set definition */
|
||
|
+
|
||
|
+/* Incompat feature set */
|
||
|
+#define BCH_FEATURE_INCOMPAT_LARGE_BUCKET 0x0001 /* 32bit bucket size */
|
||
|
+
|
||
|
#define BCH_FEATURE_COMPAT_FUNCS(name, flagname) \
|
||
|
static inline int bch_has_feature_##name(struct cache_sb *sb) \
|
||
|
{ \
|
||
|
@@ -261,4 +267,6 @@ static inline void bch_clear_feature_##name(struct cache_sb *sb) \
|
||
|
~BCH##_FEATURE_INCOMPAT_##flagname; \
|
||
|
}
|
||
|
|
||
|
+BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LARGE_BUCKET);
|
||
|
+
|
||
|
#endif
|
||
|
diff --git a/features.c b/features.c
|
||
|
index a1c9884..df15862 100644
|
||
|
--- a/features.c
|
||
|
+++ b/features.c
|
||
|
@@ -18,5 +18,7 @@ struct feature {
|
||
|
};
|
||
|
|
||
|
static struct feature feature_list[] = {
|
||
|
+ {BCH_FEATURE_INCOMPAT, BCH_FEATURE_INCOMPAT_LARGE_BUCKET,
|
||
|
+ "large_bucket"},
|
||
|
{0, 0, 0 },
|
||
|
};
|
||
|
diff --git a/lib.c b/lib.c
|
||
|
index dcf752c..efabeb1 100644
|
||
|
--- a/lib.c
|
||
|
+++ b/lib.c
|
||
|
@@ -4,6 +4,7 @@
|
||
|
#include <stdbool.h>
|
||
|
#include <blkid.h>
|
||
|
#include <dirent.h>
|
||
|
+#include <limits.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <unistd.h>
|
||
|
#include <stdio.h>
|
||
|
@@ -736,6 +737,10 @@ struct cache_sb *to_cache_sb(struct cache_sb *sb,
|
||
|
sb->feature_ro_compat = le64_to_cpu(sb_disk->feature_ro_compat);
|
||
|
}
|
||
|
|
||
|
+ if (sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES &&
|
||
|
+ bch_has_feature_large_bucket(sb))
|
||
|
+ sb->bucket_size += le16_to_cpu(sb_disk->bucket_size_hi) << 16;
|
||
|
+
|
||
|
return sb;
|
||
|
}
|
||
|
|
||
|
@@ -784,5 +789,19 @@ struct cache_sb_disk *to_cache_sb_disk(struct cache_sb_disk *sb_disk,
|
||
|
sb_disk->feature_ro_compat = cpu_to_le64(sb->feature_ro_compat);
|
||
|
}
|
||
|
|
||
|
+ if (sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES &&
|
||
|
+ bch_has_feature_large_bucket(sb))
|
||
|
+ sb_disk->bucket_size_hi = cpu_to_le16(sb->bucket_size >> 16);
|
||
|
+
|
||
|
return sb_disk;
|
||
|
}
|
||
|
+
|
||
|
+void set_bucket_size(struct cache_sb *sb, unsigned int bucket_size)
|
||
|
+{
|
||
|
+ if (bucket_size > USHRT_MAX) {
|
||
|
+ sb->version = BCACHE_SB_VERSION_CDEV_WITH_FEATURES;
|
||
|
+ bch_set_feature_large_bucket(sb);
|
||
|
+ }
|
||
|
+
|
||
|
+ sb->bucket_size = bucket_size;
|
||
|
+}
|
||
|
diff --git a/lib.h b/lib.h
|
||
|
index b37608e..1dd2bfe 100644
|
||
|
--- a/lib.h
|
||
|
+++ b/lib.h
|
||
|
@@ -52,6 +52,7 @@ int set_label(char *devname, char *label);
|
||
|
int cset_to_devname(struct list_head *head, char *cset, char *devname);
|
||
|
struct cache_sb *to_cache_sb(struct cache_sb *sb, struct cache_sb_disk *sb_disk);
|
||
|
struct cache_sb_disk *to_cache_sb_disk(struct cache_sb_disk *sb_disk,struct cache_sb *sb);
|
||
|
+void set_bucket_size(struct cache_sb *sb, unsigned int bucket_size);
|
||
|
|
||
|
#define DEVLEN sizeof(struct dev)
|
||
|
|
||
|
diff --git a/make.c b/make.c
|
||
|
index a239023..9631857 100644
|
||
|
--- a/make.c
|
||
|
+++ b/make.c
|
||
|
@@ -83,7 +83,9 @@ uint64_t hatoi(const char *s)
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
-unsigned int hatoi_validate(const char *s, const char *msg)
|
||
|
+unsigned int hatoi_validate(const char *s,
|
||
|
+ const char *msg,
|
||
|
+ unsigned long max)
|
||
|
{
|
||
|
uint64_t v = hatoi(s);
|
||
|
|
||
|
@@ -94,7 +96,7 @@ unsigned int hatoi_validate(const char *s, const char *msg)
|
||
|
|
||
|
v /= 512;
|
||
|
|
||
|
- if (v > USHRT_MAX) {
|
||
|
+ if (v > max) {
|
||
|
fprintf(stderr, "%s too large\n", msg);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
@@ -338,7 +340,7 @@ static void write_sb(char *dev, unsigned int block_size,
|
||
|
uuid_generate(sb.uuid);
|
||
|
memcpy(sb.set_uuid, set_uuid, sizeof(sb.set_uuid));
|
||
|
|
||
|
- sb.bucket_size = bucket_size;
|
||
|
+ set_bucket_size(&sb, bucket_size);
|
||
|
sb.block_size = block_size;
|
||
|
|
||
|
uuid_unparse(sb.uuid, uuid_str);
|
||
|
@@ -362,7 +364,8 @@ static void write_sb(char *dev, unsigned int block_size,
|
||
|
}
|
||
|
|
||
|
if (data_offset != BDEV_DATA_START_DEFAULT) {
|
||
|
- sb.version = BCACHE_SB_VERSION_BDEV_WITH_OFFSET;
|
||
|
+ if (sb.version < BCACHE_SB_VERSION_BDEV_WITH_OFFSET)
|
||
|
+ sb.version = BCACHE_SB_VERSION_BDEV_WITH_OFFSET;
|
||
|
sb.data_offset = data_offset;
|
||
|
}
|
||
|
|
||
|
@@ -382,6 +385,7 @@ static void write_sb(char *dev, unsigned int block_size,
|
||
|
} else {
|
||
|
sb.nbuckets = getblocks(fd) / sb.bucket_size;
|
||
|
sb.nr_in_set = 1;
|
||
|
+ /* 23 is (SB_SECTOR + SB_SIZE) - 1 sectors */
|
||
|
sb.first_bucket = (23 / sb.bucket_size) + 1;
|
||
|
|
||
|
if (sb.nbuckets < 1 << 7) {
|
||
|
@@ -538,10 +542,12 @@ int make_bcache(int argc, char **argv)
|
||
|
bdev = 1;
|
||
|
break;
|
||
|
case 'b':
|
||
|
- bucket_size = hatoi_validate(optarg, "bucket size");
|
||
|
+ bucket_size =
|
||
|
+ hatoi_validate(optarg, "bucket size", UINT_MAX);
|
||
|
break;
|
||
|
case 'w':
|
||
|
- block_size = hatoi_validate(optarg, "block size");
|
||
|
+ block_size =
|
||
|
+ hatoi_validate(optarg, "block size", USHRT_MAX);
|
||
|
break;
|
||
|
#if 0
|
||
|
case 'U':
|
||
|
--
|
||
|
2.26.2
|
||
|
|