Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
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 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...
commit 56df19116b147217e75784046491742fa24cd0cd 1 parent 445032e
@g2p authored
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,13 +60,13 @@ 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");
@@ -74,8 +74,8 @@ int main(int argc, char **argv)
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);
@@ -83,9 +83,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%" 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", 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,8 +290,8 @@ 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;
@@ -297,7 +299,7 @@ int main(int argc, char **argv)
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;
}
Please sign in to comment.
Something went wrong with that request. Please try again.