Skip to content
Browse files

Keep data offset in the superblock.

Consolidate superblock version defines, update related comments, pick a
free version number, and enable the --data-offset-sectors option.

Also make sure to copy more than sizeof(sb) so that current bdev and
cdev formats pass checksumming.  Print all known formats in
bcache-super-show.
  • Loading branch information...
1 parent 445032e commit 8c5f6f81da84dfd15bc475e555bdc879418bb033 @g2p committed Mar 9, 2013
Showing with 88 additions and 64 deletions.
  1. +42 −29 bcache-super-show.c
  2. +16 −8 bcache.h
  3. +25 −22 make-bcache.c
  4. +5 −5 probe-bcache.c
View
71 bcache-super-show.c
@@ -31,7 +31,7 @@ int main(int argc, char **argv)
bool force_csum = false;
int o;
extern char *optarg;
- struct cache_sb sb;
+ struct cache_sb *sb = calloc(1, SB_SIZE);
char uuid[40];
uint64_t expected_csum;
@@ -60,32 +60,32 @@ int main(int argc, char **argv)
exit(2);
}
- if (pread(fd, &sb, sizeof(sb), 4096) != sizeof(sb)) {
+ if (pread(fd, sb, SB_SIZE, SB_START) != SB_SIZE) {
fprintf(stderr, "Couldn't read\n");
exit(2);
}
printf("sb.magic\t\t");
- if (! memcmp(sb.magic, bcache_magic, 16)) {
+ if (! memcmp(sb->magic, bcache_magic, 16)) {
printf("ok\n");
} else {
printf("bad magic\n");
fprintf(stderr, "Invalid superblock (bad magic)\n");
exit(2);
}
- printf("sb.first_sector\t\t%" PRIu64, sb.offset);
- if (sb.offset == SB_SECTOR) {
+ printf("sb.first_sector\t\t%" PRIu64, sb->offset);
+ if (sb->offset == SB_SECTOR) {
printf(" [match]\n");
} else {
printf(" [expected %ds]\n", SB_SECTOR);
fprintf(stderr, "Invalid superblock (bad sector)\n");
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%" PRIX64, sb->csum);
+ expected_csum = csum_set(sb);
+ if (sb->csum == expected_csum) {
printf(" [match]\n");
} else {
printf(" [expected %" PRIX64 "]\n", expected_csum);
@@ -95,18 +95,24 @@ int main(int argc, char **argv)
}
}
- printf("sb.version\t\t%" PRIu64, sb.version);
- switch (sb.version) {
- case 0:
+ printf("sb.version\t\t%" PRIu64, sb->version);
+ switch (sb->version) {
+ case BCACHE_SB_VERSION_CDEV:
printf(" [cache device]\n");
break;
- // SB_BDEV macro says bdev iff version is odd; only 0 and 1
- // seem to be fully implemented however.
- case CACHE_BACKING_DEV: // 1
+ case BCACHE_SB_VERSION_CDEV_WITH_UUID:
+ printf(" [cache device (new UUID format)]\n");
+ break;
+
+ case BCACHE_SB_VERSION_BDEV:
printf(" [backing device]\n");
break;
+ case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
+ printf(" [backing device with data offset]\n");
+ break;
+
default:
printf(" [unknown]\n");
// exit code?
@@ -115,40 +121,47 @@ int main(int argc, char **argv)
putchar('\n');
- uuid_unparse(sb.uuid, uuid);
+ uuid_unparse(sb->uuid, uuid);
printf("dev.uuid\t\t%s\n", uuid);
printf(
"dev.sectors_per_block\t%u\n"
"dev.sectors_per_bucket\t%u\n"
"dev.bucket_count\t%ju\n"
- "dev.cache_count\t\t%u\n", // expect version == 0 ? 1 : 0
- sb.block_size,
- sb.bucket_size,
- sb.nbuckets,
- sb.nr_this_dev);
+ "dev.cache_count\t\t%u\n", // expect SB_IS_BDEV(version) ? 0 : 1
+ sb->block_size,
+ sb->bucket_size,
+ sb->nbuckets,
+ sb->nr_this_dev);
- if (sb.version == 0) {
+ if (! SB_IS_BDEV(sb)) {
printf(
"dev.cache.first_bucket\t%u\n"
"dev.cache.first_sector\t%u\n"
"dev.cache.discard\t%s\n",
- sb.first_bucket,
- sb.bucket_size * sb.first_bucket,
- CACHE_DISCARD(&sb) ? "yes" : "no");
- } else if (sb.version == CACHE_BACKING_DEV) {
+ sb->first_bucket,
+ sb->bucket_size * sb->first_bucket,
+ CACHE_DISCARD(sb) ? "yes" : "no");
+ } else if (sb->version == BCACHE_SB_VERSION_BDEV) {
printf(
"dev.data.first_sector\t%u\n"
"dev.data.writeback\t%s\n",
- BDEV_DATA_START,
- BDEV_WRITEBACK(&sb) ? "yes" : "no");
+ BDEV_DATA_START_DEFAULT,
+ BDEV_WRITEBACK(sb) ? "yes" : "no");
+ } else if (sb->version == BCACHE_SB_VERSION_BDEV_WITH_OFFSET) {
+ printf(
+ "dev.data.first_sector\t%lu\n"
+ "dev.data.writeback\t%s\n",
+ sb->d[0],
+ BDEV_WRITEBACK(sb) ? "yes" : "no");
}
putchar('\n');
- uuid_unparse(sb.set_uuid, uuid);
+ uuid_unparse(sb->set_uuid, uuid);
printf("cset.uuid\t\t%s\n", uuid);
- printf("cset.cache_count\t%u\n\n", sb.nr_in_set);
+ printf("cset.cache_count\t%u\n\n", sb->nr_in_set);
+ free(sb);
return 0;
}
View
24 bcache.h
@@ -15,24 +15,29 @@ static const char bcache_magic[] = {
0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca,
0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81 };
-/* Version 1: Backing dev
+/* Version 0: Cache device
+ * Version 1: Backing device
* Version 2: Seed pointer into btree node checksum
- * Version 3: Backing dev superblock has offset of start of data
+ * Version 3: Cache device with new UUID format
+ * Version 4: Backing device with data offset
*/
-
-#define BCACHE_SB_BDEV_VERSION 3
-#define BCACHE_SB_MAX_VERSION 3
+#define BCACHE_SB_VERSION_CDEV 0
+#define BCACHE_SB_VERSION_BDEV 1
+#define BCACHE_SB_VERSION_CDEV_WITH_UUID 3
+#define BCACHE_SB_VERSION_BDEV_WITH_OFFSET 4
+#define BCACHE_SB_MAX_VERSION 4
#define SB_SECTOR 8
#define SB_LABEL_SIZE 32
-#define BDEV_DATA_START 16 /* sectors */
+#define BDEV_DATA_START_DEFAULT 16 /* sectors */
+#define SB_START (SB_SECTOR * 512)
+#define SB_SIZE 4096
struct cache_sb {
uint64_t csum;
uint64_t offset; /* sector where this sb was written */
uint64_t version;
-#define CACHE_BACKING_DEV 1
uint8_t magic[16];
@@ -61,7 +66,10 @@ struct cache_sb {
uint64_t d[]; /* journal buckets */
};
-BITMASK(SB_BDEV, struct cache_sb, version, 0, 1);
+static inline bool SB_IS_BDEV(const struct cache_sb *sb) {
+ return sb->version == BCACHE_SB_VERSION_BDEV
+ || sb->version == BCACHE_SB_VERSION_BDEV_WITH_OFFSET;
+}
BITMASK(BDEV_WRITEBACK, struct cache_sb, flags, 0, 1);
View
47 make-bcache.c
@@ -136,6 +136,7 @@ void usage()
" -B, --bdev Format a backing device\n"
" -b, --bucket bucket size\n"
" -w, --block block size (hard sector size of SSD, often 2k)\n"
+ " -o, --data-offset data offset in sectors\n"
" -U UUID\n"
" --writeback enable writeback\n"
" --discard enable discards\n"
@@ -154,7 +155,7 @@ const char * const cache_replacement_policies[] = {
int writeback;
int discard;
unsigned cache_replacement_policy;
-uint64_t data_offset = BDEV_DATA_START;
+uint64_t data_offset = BDEV_DATA_START_DEFAULT;
struct option opts[] = {
{ "cache", 0, NULL, 'C' },
@@ -164,7 +165,7 @@ struct option opts[] = {
{ "writeback", 0, &writeback, 1 },
{ "discard", 0, &discard, 1 },
{ "cache_replacement_policy", 1, NULL, 'p' },
-// { "data_offset", 1, NULL, 'o' },
+ { "data-offset-sectors", 1, NULL, 'o' },
{ "help", 0, NULL, 'h' },
{ NULL, 0, NULL, 0 },
};
@@ -191,13 +192,15 @@ void write_sb(char *dev, struct cache_sb *sb)
sb->flags = 0;
- if (SB_BDEV(sb)) {
+ if (SB_IS_BDEV(sb)) {
SET_BDEV_WRITEBACK(sb, writeback);
- if (data_offset != BDEV_DATA_START) {
- sb->version = BCACHE_SB_BDEV_VERSION;
+ if (data_offset != BDEV_DATA_START_DEFAULT) {
+ sb->version = BCACHE_SB_VERSION_BDEV_WITH_OFFSET;
sb->keys = 1;
sb->d[0] = data_offset;
+ } else {
+ sb->version = BCACHE_SB_VERSION_BDEV;
}
} else {
SET_CACHE_DISCARD(sb, discard);
@@ -235,7 +238,7 @@ void write_sb(char *dev, struct cache_sb *sb)
sb->nr_this_dev,
sb->first_bucket);
- if (pwrite(fd, sb, sizeof(*sb), SB_SECTOR << 9) != sizeof(*sb)) {
+ if (pwrite(fd, sb, SB_SIZE, SB_START) != SB_SIZE) {
perror("write error\n");
exit(EXIT_FAILURE);
}
@@ -250,34 +253,33 @@ int main(int argc, char **argv)
{
bool written = false;
int c;
- struct cache_sb sb;
+ struct cache_sb *sb = calloc(1, SB_SIZE);
- memset(&sb, 0, sizeof(struct cache_sb));
- sb.version = -1;
- sb.block_size = 1;
- sb.bucket_size = 1024;
+ sb->version = -1;
+ sb->block_size = 1;
+ sb->bucket_size = 1024;
- uuid_generate(sb.uuid);
- uuid_generate(sb.set_uuid);
+ uuid_generate(sb->uuid);
+ uuid_generate(sb->set_uuid);
while ((c = getopt_long(argc, argv,
- "-hCBU:w:b:",
+ "-hoCBU:w:b:",
opts, NULL)) != -1)
switch (c) {
case 'C':
- sb.version = 0;
+ sb->version = 0;
break;
case 'B':
- sb.version = CACHE_BACKING_DEV;
+ sb->version = BCACHE_SB_VERSION_BDEV;
break;
case 'b':
- sb.bucket_size = hatoi_validate(optarg, "bucket size");
+ sb->bucket_size = hatoi_validate(optarg, "bucket size");
break;
case 'w':
- sb.block_size = hatoi_validate(optarg, "block size");
+ sb->block_size = hatoi_validate(optarg, "block size");
break;
case 'U':
- if (uuid_parse(optarg, sb.uuid)) {
+ if (uuid_parse(optarg, sb->uuid)) {
printf("Bad uuid\n");
exit(EXIT_FAILURE);
}
@@ -288,16 +290,16 @@ int main(int argc, char **argv)
break;
case 'o':
data_offset = atoll(optarg);
- if (sb.d[0] < BDEV_DATA_START) {
- printf("Bad data offset; minimum %d sectors\n", BDEV_DATA_START);
+ if (data_offset < BDEV_DATA_START_DEFAULT) {
+ printf("Bad data offset; minimum %d sectors\n", BDEV_DATA_START_DEFAULT);
exit(EXIT_FAILURE);
}
break;
case 'h':
usage();
break;
case 1:
- write_sb(optarg, &sb);
+ write_sb(optarg, sb);
written = true;
break;
}
@@ -307,5 +309,6 @@ int main(int argc, char **argv)
usage();
}
+ free(sb);
return 0;
}
View
10 probe-bcache.c
@@ -22,7 +22,7 @@ int main(int argc, char **argv)
bool udev = false;
int i, o;
extern char *optarg;
- struct cache_sb sb;
+ struct cache_sb *sb = calloc(1, SB_SIZE);
char uuid[40];
while ((o = getopt(argc, argv, "o:")) != EOF)
@@ -45,14 +45,13 @@ int main(int argc, char **argv)
if (fd == -1)
continue;
-
- if (pread(fd, &sb, sizeof(sb), 4096) != sizeof(sb))
+ if (pread(fd, sb, SB_SIZE, SB_START) != SB_SIZE)
continue;
- if (memcmp(sb.magic, bcache_magic, 16))
+ if (memcmp(sb->magic, bcache_magic, 16))
continue;
- uuid_unparse(sb.uuid, uuid);
+ uuid_unparse(sb->uuid, uuid);
if (udev)
printf("ID_FS_UUID=%s\n"
@@ -63,5 +62,6 @@ int main(int argc, char **argv)
printf("%s: UUID=\"\" TYPE=\"bcache\"\n", uuid);
}
+ free(sb);
return 0;
}

0 comments on commit 8c5f6f8

Please sign in to comment.
Something went wrong with that request. Please try again.