forked from pool/bcache-tools
444 lines
13 KiB
Diff
444 lines
13 KiB
Diff
|
From 2891723d70759fb9d11cd74943ad72de9bfe092e Mon Sep 17 00:00:00 2001
|
||
|
From: Coly Li <colyli@suse.de>
|
||
|
Date: Mon, 17 Aug 2020 00:15:26 +0800
|
||
|
Subject: [PATCH 08/17] bcache-tools: define separated super block for
|
||
|
in-memory and on-disk format
|
||
|
Git-commit: 2891723d70759fb9d11cd74943ad72de9bfe092e
|
||
|
Patch-mainline: bcache-tools-1.1
|
||
|
References: jsc#SLE-9807
|
||
|
|
||
|
This patch syncrhonizes the super block definition from bcache kernel
|
||
|
code, now the original super block structure is changed into two,
|
||
|
- struct cache_sb_disk
|
||
|
This is for on-disk bcache super block format, which is exactly same
|
||
|
as original struct cache_sb.
|
||
|
- struct cache_sb
|
||
|
This is only for in-memory super block, it is no longer exactly
|
||
|
mapping to the members and offsets to the cache_sb_disk.
|
||
|
|
||
|
Most part of the patch is to make source code to be consistent to the
|
||
|
data structures change.
|
||
|
|
||
|
Signed-off-by: Coly Li <colyli@suse.de>
|
||
|
---
|
||
|
Makefile | 2 +-
|
||
|
bcache-super-show.c | 22 +++++++++++--------
|
||
|
bcache.h | 49 ++++++++++++++++++++++--------------------
|
||
|
lib.c | 18 +++++++++++-----
|
||
|
make.c | 52 ++++++++++-----------------------------------
|
||
|
probe-bcache.c | 8 +++----
|
||
|
6 files changed, 68 insertions(+), 83 deletions(-)
|
||
|
|
||
|
diff --git a/Makefile b/Makefile
|
||
|
index 2c326cf..b4546a1 100644
|
||
|
--- a/Makefile
|
||
|
+++ b/Makefile
|
||
|
@@ -31,7 +31,7 @@ probe-bcache: CFLAGS += `pkg-config --cflags uuid blkid`
|
||
|
|
||
|
bcache-super-show: LDLIBS += `pkg-config --libs uuid`
|
||
|
bcache-super-show: CFLAGS += -std=gnu99
|
||
|
-bcache-super-show: crc64.o
|
||
|
+bcache-super-show: crc64.o lib.o
|
||
|
|
||
|
bcache-register: bcache-register.o
|
||
|
|
||
|
diff --git a/bcache-super-show.c b/bcache-super-show.c
|
||
|
index 26cc40e..883410f 100644
|
||
|
--- a/bcache-super-show.c
|
||
|
+++ b/bcache-super-show.c
|
||
|
@@ -25,7 +25,8 @@
|
||
|
#include <uuid/uuid.h>
|
||
|
|
||
|
#include "bcache.h"
|
||
|
-
|
||
|
+#include "lib.h"
|
||
|
+#include "bitwise.h"
|
||
|
|
||
|
static void usage()
|
||
|
{
|
||
|
@@ -61,6 +62,7 @@ int main(int argc, char **argv)
|
||
|
bool force_csum = false;
|
||
|
int o;
|
||
|
extern char *optarg;
|
||
|
+ struct cache_sb_disk sb_disk;
|
||
|
struct cache_sb sb;
|
||
|
char uuid[40];
|
||
|
uint64_t expected_csum;
|
||
|
@@ -90,11 +92,13 @@ int main(int argc, char **argv)
|
||
|
exit(2);
|
||
|
}
|
||
|
|
||
|
- if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
|
||
|
+ if (pread(fd, &sb_disk, sizeof(sb_disk), SB_START) != sizeof(sb_disk)) {
|
||
|
fprintf(stderr, "Couldn't read\n");
|
||
|
exit(2);
|
||
|
}
|
||
|
|
||
|
+ to_cache_sb(&sb, &sb_disk);
|
||
|
+
|
||
|
printf("sb.magic\t\t");
|
||
|
if (!memcmp(sb.magic, bcache_magic, 16)) {
|
||
|
printf("ok\n");
|
||
|
@@ -104,7 +108,7 @@ int main(int argc, char **argv)
|
||
|
exit(2);
|
||
|
}
|
||
|
|
||
|
- printf("sb.first_sector\t\t%" PRIu64, sb.offset);
|
||
|
+ printf("sb.first_sector\t\t%llu", sb.offset);
|
||
|
if (sb.offset == SB_SECTOR) {
|
||
|
printf(" [match]\n");
|
||
|
} else {
|
||
|
@@ -113,9 +117,9 @@ int main(int argc, char **argv)
|
||
|
exit(2);
|
||
|
}
|
||
|
|
||
|
- printf("sb.csum\t\t\t%" PRIX64, sb.csum);
|
||
|
- expected_csum = csum_set(&sb);
|
||
|
- if (sb.csum == expected_csum) {
|
||
|
+ printf("sb.csum\t\t\t%llx", le64_to_cpu(sb_disk.csum));
|
||
|
+ expected_csum = csum_set(&sb_disk);
|
||
|
+ if (le64_to_cpu(sb_disk.csum) == expected_csum) {
|
||
|
printf(" [match]\n");
|
||
|
} else {
|
||
|
printf(" [expected %" PRIX64 "]\n", expected_csum);
|
||
|
@@ -125,7 +129,7 @@ int main(int argc, char **argv)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- printf("sb.version\t\t%" PRIu64, sb.version);
|
||
|
+ printf("sb.version\t\t%llu", sb.version);
|
||
|
switch (sb.version) {
|
||
|
// These are handled the same by the kernel
|
||
|
case BCACHE_SB_VERSION_CDEV:
|
||
|
@@ -168,8 +172,8 @@ int main(int argc, char **argv)
|
||
|
if (!SB_IS_BDEV(&sb)) {
|
||
|
// total_sectors includes the superblock;
|
||
|
printf("dev.cache.first_sector\t%u\n"
|
||
|
- "dev.cache.cache_sectors\t%ju\n"
|
||
|
- "dev.cache.total_sectors\t%ju\n"
|
||
|
+ "dev.cache.cache_sectors\t%llu\n"
|
||
|
+ "dev.cache.total_sectors\t%llu\n"
|
||
|
"dev.cache.ordered\t%s\n"
|
||
|
"dev.cache.discard\t%s\n"
|
||
|
"dev.cache.pos\t\t%u\n"
|
||
|
diff --git a/bcache.h b/bcache.h
|
||
|
index 82fe580..250da9d 100644
|
||
|
--- a/bcache.h
|
||
|
+++ b/bcache.h
|
||
|
@@ -94,38 +94,41 @@ struct cache_sb_disk {
|
||
|
__le64 d[SB_JOURNAL_BUCKETS]; /* journal buckets */
|
||
|
};
|
||
|
|
||
|
+/*
|
||
|
+ * This is for in-memory bcache super block.
|
||
|
+ * NOTE: cache_sb is NOT exactly mapping to cache_sb_disk, the member
|
||
|
+ * size, ordering and even whole struct size may be different
|
||
|
+ * from cache_sb_disk.
|
||
|
+ */
|
||
|
struct cache_sb {
|
||
|
- uint64_t csum;
|
||
|
- uint64_t offset; /* sector where this sb was written */
|
||
|
- uint64_t version;
|
||
|
+ __u64 offset; /* sector where this sb was written */
|
||
|
+ __u64 version;
|
||
|
|
||
|
- uint8_t magic[16];
|
||
|
+ __u8 magic[16];
|
||
|
|
||
|
- uint8_t uuid[16];
|
||
|
+ __u8 uuid[16];
|
||
|
union {
|
||
|
- uint8_t set_uuid[16];
|
||
|
- uint64_t set_magic;
|
||
|
+ __u8 set_uuid[16];
|
||
|
+ __u64 set_magic;
|
||
|
};
|
||
|
- uint8_t label[SB_LABEL_SIZE];
|
||
|
+ __u8 label[SB_LABEL_SIZE];
|
||
|
|
||
|
- uint64_t flags;
|
||
|
- uint64_t seq;
|
||
|
- uint64_t pad[8];
|
||
|
+ __u64 flags;
|
||
|
+ __u64 seq;
|
||
|
|
||
|
union {
|
||
|
struct {
|
||
|
/* Cache devices */
|
||
|
- uint64_t nbuckets; /* device size */
|
||
|
-
|
||
|
- uint16_t block_size; /* sectors */
|
||
|
- uint16_t bucket_size; /* sectors */
|
||
|
+ __u64 nbuckets; /* device size */
|
||
|
|
||
|
- uint16_t nr_in_set;
|
||
|
- uint16_t nr_this_dev;
|
||
|
+ __u16 block_size; /* sectors */
|
||
|
+ __u16 nr_in_set;
|
||
|
+ __u16 nr_this_dev;
|
||
|
+ __u32 bucket_size; /* sectors */
|
||
|
};
|
||
|
struct {
|
||
|
/* Backing devices */
|
||
|
- uint64_t data_offset;
|
||
|
+ __u64 data_offset;
|
||
|
|
||
|
/*
|
||
|
* block_size from the cache device section is still used by
|
||
|
@@ -135,14 +138,14 @@ struct cache_sb {
|
||
|
};
|
||
|
};
|
||
|
|
||
|
- uint32_t last_mount; /* time_t */
|
||
|
+ __u32 last_mount; /* time overflow in y2106 */
|
||
|
|
||
|
- uint16_t first_bucket;
|
||
|
+ __u16 first_bucket;
|
||
|
union {
|
||
|
- uint16_t njournal_buckets;
|
||
|
- uint16_t keys;
|
||
|
+ __u16 njournal_buckets;
|
||
|
+ __u16 keys;
|
||
|
};
|
||
|
- uint64_t d[SB_JOURNAL_BUCKETS]; /* journal buckets */
|
||
|
+ __u64 d[SB_JOURNAL_BUCKETS]; /* journal buckets */
|
||
|
};
|
||
|
|
||
|
static inline bool SB_IS_BDEV(const struct cache_sb *sb)
|
||
|
diff --git a/lib.c b/lib.c
|
||
|
index 542f115..9a2fa26 100644
|
||
|
--- a/lib.c
|
||
|
+++ b/lib.c
|
||
|
@@ -293,7 +293,6 @@ int detail_base(char *devname, struct cache_sb sb, struct dev *base)
|
||
|
strcpy(base->name, devname);
|
||
|
base->magic = "ok";
|
||
|
base->first_sector = SB_SECTOR;
|
||
|
- base->csum = sb.csum;
|
||
|
base->version = sb.version;
|
||
|
|
||
|
strncpy(base->label, (char *) sb.label, SB_LABEL_SIZE);
|
||
|
@@ -325,6 +324,7 @@ int detail_base(char *devname, struct cache_sb sb, struct dev *base)
|
||
|
|
||
|
int may_add_item(char *devname, struct list_head *head)
|
||
|
{
|
||
|
+ struct cache_sb_disk sb_disk;
|
||
|
struct cache_sb sb;
|
||
|
|
||
|
if (strcmp(devname, ".") == 0 || strcmp(devname, "..") == 0)
|
||
|
@@ -336,10 +336,13 @@ int may_add_item(char *devname, struct list_head *head)
|
||
|
|
||
|
if (fd == -1)
|
||
|
return 0;
|
||
|
- if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
|
||
|
+ if (pread(fd, &sb_disk, sizeof(sb_disk), SB_START) != sizeof(sb_disk)) {
|
||
|
close(fd);
|
||
|
return 0;
|
||
|
}
|
||
|
+
|
||
|
+ to_cache_sb(&sb, &sb_disk);
|
||
|
+
|
||
|
if (memcmp(sb.magic, bcache_magic, 16)) {
|
||
|
close(fd);
|
||
|
return 0;
|
||
|
@@ -348,6 +351,8 @@ int may_add_item(char *devname, struct list_head *head)
|
||
|
int ret;
|
||
|
|
||
|
tmp = (struct dev *) malloc(DEVLEN);
|
||
|
+
|
||
|
+ tmp->csum = le64_to_cpu(sb_disk.csum);
|
||
|
ret = detail_base(dev, sb, tmp);
|
||
|
if (ret != 0) {
|
||
|
fprintf(stderr, "Failed to get information for %s\n", dev);
|
||
|
@@ -399,6 +404,7 @@ int list_bdevs(struct list_head *head)
|
||
|
|
||
|
int detail_dev(char *devname, struct bdev *bd, struct cdev *cd, int *type)
|
||
|
{
|
||
|
+ struct cache_sb_disk sb_disk;
|
||
|
struct cache_sb sb;
|
||
|
uint64_t expected_csum;
|
||
|
int fd = open(devname, O_RDONLY);
|
||
|
@@ -408,11 +414,13 @@ int detail_dev(char *devname, struct bdev *bd, struct cdev *cd, int *type)
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
- if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
|
||
|
+ if (pread(fd, &sb_disk, sizeof(sb_disk), SB_START) != sizeof(sb_disk)) {
|
||
|
fprintf(stderr, "Couldn't read\n");
|
||
|
goto Fail;
|
||
|
}
|
||
|
|
||
|
+ to_cache_sb(&sb, &sb_disk);
|
||
|
+
|
||
|
if (memcmp(sb.magic, bcache_magic, 16)) {
|
||
|
fprintf(stderr,
|
||
|
"Bad magic,make sure this is an bcache device\n");
|
||
|
@@ -424,8 +432,8 @@ int detail_dev(char *devname, struct bdev *bd, struct cdev *cd, int *type)
|
||
|
goto Fail;
|
||
|
}
|
||
|
|
||
|
- expected_csum = csum_set(&sb);
|
||
|
- if (!(sb.csum == expected_csum)) {
|
||
|
+ expected_csum = csum_set(&sb_disk);
|
||
|
+ if (le64_to_cpu(sb_disk.csum) != expected_csum) {
|
||
|
fprintf(stderr, "Csum is not match with expected one\n");
|
||
|
goto Fail;
|
||
|
}
|
||
|
diff --git a/make.c b/make.c
|
||
|
index cc76863..a239023 100644
|
||
|
--- a/make.c
|
||
|
+++ b/make.c
|
||
|
@@ -223,35 +223,6 @@ err:
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
-static void swap_sb(struct cache_sb *sb, int write_cdev_super)
|
||
|
-{
|
||
|
- int i;
|
||
|
-
|
||
|
- /* swap to little endian byte order to write */
|
||
|
- sb->offset = cpu_to_le64(sb->offset);
|
||
|
- sb->version = cpu_to_le64(sb->version);
|
||
|
- sb->flags = cpu_to_le64(sb->flags);
|
||
|
- sb->seq = cpu_to_le64(sb->seq);
|
||
|
- sb->last_mount = cpu_to_le32(sb->last_mount);
|
||
|
- sb->first_bucket = cpu_to_le16(sb->first_bucket);
|
||
|
- sb->keys = cpu_to_le16(sb->keys);
|
||
|
- sb->block_size = cpu_to_le16(sb->block_size);
|
||
|
-
|
||
|
- for (i = 0; i < SB_JOURNAL_BUCKETS; i++)
|
||
|
- sb->d[i] = cpu_to_le64(sb->d[i]);
|
||
|
-
|
||
|
- if (write_cdev_super) {
|
||
|
- /* Cache devices */
|
||
|
- sb->nbuckets = cpu_to_le64(sb->nbuckets);
|
||
|
- sb->bucket_size = cpu_to_le16(sb->bucket_size);
|
||
|
- sb->nr_in_set = cpu_to_le16(sb->nr_in_set);
|
||
|
- sb->nr_this_dev = cpu_to_le16(sb->nr_this_dev);
|
||
|
- } else {
|
||
|
- /* Backing devices */
|
||
|
- sb->data_offset = cpu_to_le64(sb->data_offset);
|
||
|
- }
|
||
|
-}
|
||
|
-
|
||
|
static void write_sb(char *dev, unsigned int block_size,
|
||
|
unsigned int bucket_size,
|
||
|
bool writeback, bool discard, bool wipe_bcache,
|
||
|
@@ -261,9 +232,9 @@ static void write_sb(char *dev, unsigned int block_size,
|
||
|
{
|
||
|
int fd;
|
||
|
char uuid_str[40], set_uuid_str[40], zeroes[SB_START] = {0};
|
||
|
+ struct cache_sb_disk sb_disk;
|
||
|
struct cache_sb sb;
|
||
|
blkid_probe pr;
|
||
|
- int write_cdev_super = 1;
|
||
|
|
||
|
fd = open(dev, O_RDWR|O_EXCL);
|
||
|
|
||
|
@@ -320,13 +291,13 @@ static void write_sb(char *dev, unsigned int block_size,
|
||
|
if (force)
|
||
|
wipe_bcache = true;
|
||
|
|
||
|
- if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb))
|
||
|
+ if (pread(fd, &sb_disk, sizeof(sb_disk), SB_START) != sizeof(sb_disk))
|
||
|
exit(EXIT_FAILURE);
|
||
|
|
||
|
- if (!memcmp(sb.magic, bcache_magic, 16)) {
|
||
|
+ if (!memcmp(sb_disk.magic, bcache_magic, 16)) {
|
||
|
if (wipe_bcache) {
|
||
|
- if (pwrite(fd, zeroes, sizeof(sb),
|
||
|
- SB_START) != sizeof(sb)) {
|
||
|
+ if (pwrite(fd, zeroes, sizeof(sb_disk),
|
||
|
+ SB_START) != sizeof(sb_disk)) {
|
||
|
fprintf(stderr,
|
||
|
"Failed to erase super block for %s\n",
|
||
|
dev);
|
||
|
@@ -355,6 +326,7 @@ static void write_sb(char *dev, unsigned int block_size,
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
+ memset(&sb_disk, 0, sizeof(struct cache_sb_disk));
|
||
|
memset(&sb, 0, sizeof(struct cache_sb));
|
||
|
|
||
|
sb.offset = SB_SECTOR;
|
||
|
@@ -373,8 +345,6 @@ static void write_sb(char *dev, unsigned int block_size,
|
||
|
uuid_unparse(sb.set_uuid, set_uuid_str);
|
||
|
|
||
|
if (SB_IS_BDEV(&sb)) {
|
||
|
- write_cdev_super = 0;
|
||
|
-
|
||
|
SET_BDEV_CACHE_MODE(&sb, writeback ?
|
||
|
CACHE_MODE_WRITEBACK : CACHE_MODE_WRITETHROUGH);
|
||
|
|
||
|
@@ -415,7 +385,7 @@ static void write_sb(char *dev, unsigned int block_size,
|
||
|
sb.first_bucket = (23 / sb.bucket_size) + 1;
|
||
|
|
||
|
if (sb.nbuckets < 1 << 7) {
|
||
|
- fprintf(stderr, "Not enough buckets: %ju, need %u\n",
|
||
|
+ fprintf(stderr, "Not enough buckets: %llu, need %u\n",
|
||
|
sb.nbuckets, 1 << 7);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
@@ -429,7 +399,7 @@ static void write_sb(char *dev, unsigned int block_size,
|
||
|
printf("UUID: %s\n"
|
||
|
"Set UUID: %s\n"
|
||
|
"version: %u\n"
|
||
|
- "nbuckets: %ju\n"
|
||
|
+ "nbuckets: %llu\n"
|
||
|
"block_size_in_sectors: %u\n"
|
||
|
"bucket_size_in_sectors: %u\n"
|
||
|
"nr_in_set: %u\n"
|
||
|
@@ -462,17 +432,17 @@ static void write_sb(char *dev, unsigned int block_size,
|
||
|
* Swap native bytes order to little endian for writing
|
||
|
* the super block out.
|
||
|
*/
|
||
|
- swap_sb(&sb, write_cdev_super);
|
||
|
+ to_cache_sb_disk(&sb_disk, &sb);
|
||
|
|
||
|
/* write csum */
|
||
|
- sb.csum = csum_set(&sb);
|
||
|
+ sb_disk.csum = cpu_to_le64(csum_set(&sb_disk));
|
||
|
/* Zero start of disk */
|
||
|
if (pwrite(fd, zeroes, SB_START, 0) != SB_START) {
|
||
|
perror("write error\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
/* Write superblock */
|
||
|
- if (pwrite(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
|
||
|
+ if (pwrite(fd, &sb_disk, sizeof(sb_disk), SB_START) != sizeof(sb_disk)) {
|
||
|
perror("write error\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
diff --git a/probe-bcache.c b/probe-bcache.c
|
||
|
index c94c972..a640046 100644
|
||
|
--- a/probe-bcache.c
|
||
|
+++ b/probe-bcache.c
|
||
|
@@ -29,7 +29,7 @@ int main(int argc, char **argv)
|
||
|
bool udev = false;
|
||
|
int i, o;
|
||
|
extern char *optarg;
|
||
|
- struct cache_sb sb;
|
||
|
+ struct cache_sb_disk sb_disk;
|
||
|
char uuid[40];
|
||
|
blkid_probe pr;
|
||
|
|
||
|
@@ -66,13 +66,13 @@ int main(int argc, char **argv)
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
- if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb))
|
||
|
+ if (pread(fd, &sb_disk, sizeof(sb_disk), SB_START) != sizeof(sb_disk))
|
||
|
continue;
|
||
|
|
||
|
- if (memcmp(sb.magic, bcache_magic, 16))
|
||
|
+ if (memcmp(sb_disk.magic, bcache_magic, 16))
|
||
|
continue;
|
||
|
|
||
|
- uuid_unparse(sb.uuid, uuid);
|
||
|
+ uuid_unparse(sb_disk.uuid, uuid);
|
||
|
|
||
|
if (udev)
|
||
|
printf("ID_FS_UUID=%s\n"
|
||
|
--
|
||
|
2.26.2
|
||
|
|