From c798b43aded89d8161d924316bd5a80c4956b009 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Mon, 25 Jul 2011 00:18:42 -0700 Subject: [PATCH] New superblock format --- bcache.h | 68 ++++++++++++++++++++++++++++--------------------- make-bcache.c | 70 ++++++++++++++++++++++++--------------------------- 2 files changed, 73 insertions(+), 65 deletions(-) diff --git a/bcache.h b/bcache.h index 6e62b6b1..5cf08bc1 100644 --- a/bcache.h +++ b/bcache.h @@ -5,40 +5,52 @@ static const char bcache_magic[] = { 0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca, 0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81 }; +#define SB_LABEL_SIZE 32 + +struct cache_sb { + uint64_t csum; + uint64_t offset_this_sb; + uint64_t version; +#define CACHE_BACKING_DEV 1 + + uint8_t magic[16]; + + uint8_t uuid[16]; + uint8_t set_uuid[16]; + uint8_t label[SB_LABEL_SIZE]; + +#define CACHE_SYNC (1U << 0) + +#define BDEV_WRITEBACK_BIT 0U + +#define BDEV_STATE_NONE 0U +#define BDEV_STATE_CLEAN 1U +#define BDEV_STATE_DIRTY 2U +#define BDEV_STATE_STALE 3U + uint64_t flags; + uint64_t sequence; + uint64_t pad[8]; + + uint64_t nbuckets; /* device size */ + uint16_t block_size; /* sectors */ + uint16_t bucket_size; /* sectors */ + + uint16_t nr_in_set; + uint16_t nr_this_dev; + + uint32_t last_mount; /* time_t */ + + uint16_t first_bucket; + uint16_t njournal_buckets; + uint64_t journal_buckets[]; +}; + struct bkey { uint64_t header; uint64_t key; uint64_t ptr[]; }; -struct cache_sb { - uint8_t magic[16]; - uint8_t uuid[16]; - uint8_t set_uuid[16]; - uint64_t sequence; - -#define CACHE_CLEAN 1 -#define CACHE_SYNC 2 -#define CACHE_BACKING_DEV 4 - uint32_t version; - uint16_t block_size; /* sectors */ - uint16_t bucket_size; /* sectors */ - uint32_t journal_start; /* buckets */ - uint32_t first_bucket; /* start of data */ - uint64_t nbuckets; /* device size */ - - union { - struct bkey btree_root; - uint64_t _pad[8]; - }; - uint16_t btree_level; - uint16_t nr_in_set; - uint16_t nr_this_dev; - uint16_t _pad[1]; -#define SB_LABEL_SIZE 32 - uint8_t label[SB_LABEL_SIZE]; -}; - struct bucket_disk { uint16_t priority; uint8_t generation; diff --git a/make-bcache.c b/make-bcache.c index 3d2d3a2c..7ab2405e 100644 --- a/make-bcache.c +++ b/make-bcache.c @@ -2,6 +2,8 @@ #define __USE_FILE_OFFSET64 #define _XOPEN_SOURCE 600 +#include +#include #include #include #include @@ -64,7 +66,6 @@ void usage() " -B Format a backing device\n" " -b bucket size\n" " -w block size (hard sector size of SSD, often 2k)\n" - " -j journal size, in buckets\n" " -U UUID\n" " -S Set UUID\n"); exit(EXIT_FAILURE); @@ -73,9 +74,9 @@ void usage() int main(int argc, char **argv) { bool cache = false, backingdev = false; - int64_t nblocks, journal = 0; - int fd, i, c; - char uuid[40], set_uuid[40]; + int fd, c; + int64_t nblocks; + char uuid[40], set_uuid[40], *dev; struct cache_sb sb; memset(&sb, 0, sizeof(struct cache_sb)); @@ -97,9 +98,6 @@ int main(int argc, char **argv) case 'w': sb.block_size = hatoi(optarg) / 512; break; - case 'j': - journal = atoi(optarg); - break; case 'U': if (uuid_parse(optarg, sb.uuid)) { printf("Bad uuid\n"); @@ -130,51 +128,49 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - fd = open(argv[optind], O_RDWR); + dev = argv[optind]; + fd = open(dev, O_RDWR); if (fd == -1) { - perror("Can't open dev\n"); + printf("Can't open dev %s: %s\n", dev, strerror(errno)); exit(EXIT_FAILURE); } nblocks = getblocks(fd); printf("device is %ju sectors\n", nblocks); - if (sb.bucket_size < sb.block_size || - sb.bucket_size > nblocks / 8) { - printf("Bad bucket size %i\n", sb.bucket_size); - exit(EXIT_FAILURE); - } - + sb.offset_this_sb = 8; memcpy(sb.magic, bcache_magic, 16); - sb.version = backingdev ? CACHE_BACKING_DEV : 0; - sb.nbuckets = nblocks / sb.bucket_size; - sb.nr_in_set = 1; + sb.version = backingdev ? CACHE_BACKING_DEV : 0; + sb.nbuckets = nblocks / sb.bucket_size; + sb.nr_in_set = 1; uuid_unparse(sb.uuid, uuid); uuid_unparse(sb.set_uuid, set_uuid); - sb.journal_start = ((sb.nbuckets * sizeof(struct bucket_disk)) + (24 << 9)) / (sb.bucket_size << 9) + 1; - sb.first_bucket = sb.journal_start + journal; + sb.first_bucket = (23 / sb.bucket_size) + 1; - printf("block_size: %u\n" - "bucket_size: %u\n" - "journal_start: %u\n" - "first_bucket: %u\n" + if (cache) + if (sb.bucket_size < sb.block_size || + sb.bucket_size > nblocks / 8) { + printf("Bad bucket size %i\n", sb.bucket_size); + exit(EXIT_FAILURE); + } + + printf("UUID: %s\n" + "Set UUID: %s\n" "nbuckets: %ju\n" - "UUID: %s\n" - "Set UUID: %s\n", + "block_size: %u\n" + "bucket_size: %u\n" + "nr_in_set: %u\n" + "nr_this_dev: %u\n" + "first_bucket: %u\n" + "sizeof sb: %lu\n", + uuid, set_uuid, + sb.nbuckets, sb.block_size, sb.bucket_size, - sb.journal_start, + sb.nr_in_set, + sb.nr_this_dev, sb.first_bucket, - sb.nbuckets, - uuid, set_uuid); - - if (!backingdev) { - /* Zero out priorities */ - lseek(fd, 4096, SEEK_SET); - for (i = 8; i < sb.first_bucket * sb.bucket_size; i++) - if (write(fd, zero, 512) != 512) - goto err; - } + sizeof(sb)); if (pwrite(fd, &sb, sizeof(sb), 4096) != sizeof(sb)) goto err;