From 335ac31ba59bb37bcb9e8f9a7dbb2de657135980 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Tue, 9 Apr 2013 13:29:06 -0700 Subject: [PATCH] Fix option parsing so that passing --bucket_size after the device works This makes supporting -U more annoying; dropping that for the moment, unless someone complains --- make-bcache.c | 183 ++++++++++++++++++++++++++++---------------------- 1 file changed, 103 insertions(+), 80 deletions(-) diff --git a/make-bcache.c b/make-bcache.c index 5f4ebcca..5f327372 100644 --- a/make-bcache.c +++ b/make-bcache.c @@ -136,7 +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" - " -U UUID\n" +// " -U UUID\n" " --writeback enable writeback\n" " --discard enable discards\n" " --cache_replacement_policy=(lru|fifo)\n" @@ -151,37 +151,36 @@ const char * const cache_replacement_policies[] = { NULL }; -int writeback; -int discard; -unsigned cache_replacement_policy; -uint64_t data_offset = BDEV_DATA_START; - -struct option opts[] = { - { "cache", 0, NULL, 'C' }, - { "bdev", 0, NULL, 'B' }, - { "bucket", 1, NULL, 'b' }, - { "block", 1, NULL, 'w' }, - { "writeback", 0, &writeback, 1 }, - { "discard", 0, &discard, 1 }, - { "cache_replacement_policy", 1, NULL, 'p' }, -// { "data_offset", 1, NULL, 'o' }, - { "help", 0, NULL, 'h' }, - { NULL, 0, NULL, 0 }, -}; - -void write_sb(char *dev, struct cache_sb *sb) +static void write_sb(char *dev, unsigned block_size, unsigned bucket_size, + bool writeback, bool discard, + unsigned cache_replacement_policy, + uint64_t data_offset, + uuid_t set_uuid, bool bdev) { int fd; - char uuid[40], set_uuid[40]; + char uuid_str[40], set_uuid_str[40]; + struct cache_sb sb; - if (sb->version > BCACHE_SB_MAX_VERSION) { - printf("Must specify one of -C or -B\n"); - usage(); - } + memset(&sb, 0, sizeof(struct cache_sb)); - if (sb->bucket_size < sb->block_size) { - printf("Bucket size cannot be smaller than block size\n"); - exit(EXIT_FAILURE); + sb.version = bdev ? CACHE_BACKING_DEV : 0; + sb.bucket_size = bucket_size; + sb.block_size = block_size; + + uuid_generate(sb.uuid); + memcpy(sb.set_uuid, set_uuid, sizeof(sb.set_uuid)); + + if (SB_BDEV(&sb)) { + SET_BDEV_WRITEBACK(&sb, writeback); + + if (data_offset != BDEV_DATA_START) { + sb.version = BCACHE_SB_BDEV_VERSION; + sb.keys = 1; + sb.d[0] = data_offset; + } + } else { + SET_CACHE_DISCARD(&sb, discard); + SET_CACHE_REPLACEMENT(&sb, cache_replacement_policy); } if ((fd = open(dev, O_RDWR|O_EXCL)) == -1) { @@ -189,106 +188,108 @@ void write_sb(char *dev, struct cache_sb *sb) exit(EXIT_FAILURE); } - sb->flags = 0; + sb.offset = SB_SECTOR; + memcpy(sb.magic, bcache_magic, 16); + sb.nbuckets = getblocks(fd) / sb.bucket_size; + sb.nr_in_set = 1; + sb.first_bucket = (23 / sb.bucket_size) + 1; + sb.csum = csum_set(&sb); - if (SB_BDEV(sb)) { - SET_BDEV_WRITEBACK(sb, writeback); - - if (data_offset != BDEV_DATA_START) { - sb->version = BCACHE_SB_BDEV_VERSION; - sb->keys = 1; - sb->d[0] = data_offset; - } - } else { - SET_CACHE_DISCARD(sb, discard); - SET_CACHE_REPLACEMENT(sb, cache_replacement_policy); - } - - sb->offset = SB_SECTOR; - memcpy(sb->magic, bcache_magic, 16); - sb->nbuckets = getblocks(fd) / sb->bucket_size; - sb->nr_in_set = 1; - sb->first_bucket = (23 / sb->bucket_size) + 1; - uuid_unparse(sb->uuid, uuid); - uuid_unparse(sb->set_uuid, set_uuid); - sb->csum = csum_set(sb); - - if (sb->nbuckets < 1 << 7) { + if (sb.nbuckets < 1 << 7) { printf("Not enough buckets: %ju, need %u\n", - sb->nbuckets, 1 << 7); + sb.nbuckets, 1 << 7); exit(EXIT_FAILURE); } + uuid_unparse(sb.uuid, uuid_str); + uuid_unparse(sb.set_uuid, set_uuid_str); + printf("UUID: %s\n" "Set UUID: %s\n" + "version: %u\n" "nbuckets: %ju\n" "block_size: %u\n" "bucket_size: %u\n" "nr_in_set: %u\n" "nr_this_dev: %u\n" "first_bucket: %u\n", - uuid, set_uuid, - sb->nbuckets, - sb->block_size, - sb->bucket_size, - sb->nr_in_set, - sb->nr_this_dev, - sb->first_bucket); + uuid_str, set_uuid_str, + (unsigned) sb.version, + sb.nbuckets, + sb.block_size, + sb.bucket_size, + sb.nr_in_set, + sb.nr_this_dev, + sb.first_bucket); - if (pwrite(fd, sb, sizeof(*sb), SB_SECTOR << 9) != sizeof(*sb)) { + if (pwrite(fd, &sb, sizeof(sb), SB_SECTOR << 9) != sizeof(sb)) { perror("write error\n"); exit(EXIT_FAILURE); } fsync(fd); close(fd); - - uuid_generate(sb->uuid); } int main(int argc, char **argv) { - bool written = false; - int c; - struct cache_sb sb; + int c, bdev = -1; + unsigned i, ncache_devices = 0, nbacking_devices = 0; + char *cache_devices[argc]; + char *backing_devices[argc]; - memset(&sb, 0, sizeof(struct cache_sb)); - sb.version = -1; - sb.block_size = 1; - sb.bucket_size = 1024; + unsigned block_size = 1, bucket_size = 1024; + int writeback = 0, discard = 0; + unsigned cache_replacement_policy = 0; + uint64_t data_offset = BDEV_DATA_START; + uuid_t set_uuid; - uuid_generate(sb.uuid); - uuid_generate(sb.set_uuid); + uuid_generate(set_uuid); + + struct option opts[] = { + { "cache", 0, NULL, 'C' }, + { "bdev", 0, NULL, 'B' }, + { "bucket", 1, NULL, 'b' }, + { "block", 1, NULL, 'w' }, + { "writeback", 0, &writeback, 1 }, + { "discard", 0, &discard, 1 }, + { "cache_replacement_policy", 1, NULL, 'p' }, + { "data_offset", 1, NULL, 'o' }, + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, + }; while ((c = getopt_long(argc, argv, "-hCBU:w:b:", opts, NULL)) != -1) switch (c) { case 'C': - sb.version = 0; + bdev = 0; break; case 'B': - sb.version = CACHE_BACKING_DEV; + bdev = 1; break; case 'b': - sb.bucket_size = hatoi_validate(optarg, "bucket size"); + bucket_size = hatoi_validate(optarg, "bucket size"); break; case 'w': - sb.block_size = hatoi_validate(optarg, "block size"); + block_size = hatoi_validate(optarg, "block size"); break; +#if 0 case 'U': if (uuid_parse(optarg, sb.uuid)) { printf("Bad uuid\n"); exit(EXIT_FAILURE); } break; +#endif case 'p': cache_replacement_policy = read_string_list(optarg, cache_replacement_policies); break; case 'o': data_offset = atoll(optarg); - if (sb.d[0] < BDEV_DATA_START) { + if (data_offset < BDEV_DATA_START) { printf("Bad data offset; minimum %d sectors\n", BDEV_DATA_START); exit(EXIT_FAILURE); } @@ -297,15 +298,37 @@ int main(int argc, char **argv) usage(); break; case 1: - write_sb(optarg, &sb); - written = true; + if (bdev == -1) { + printf("Please specify -C or -B\n"); + exit(EXIT_FAILURE); + } + + if (bdev) + backing_devices[nbacking_devices++] = optarg; + else + cache_devices[ncache_devices++] = optarg; break; } - if (!written) { + if (!ncache_devices && !nbacking_devices) { printf("Please supply a device\n"); usage(); } + if (bucket_size < block_size) { + printf("Bucket size cannot be smaller than block size\n"); + exit(EXIT_FAILURE); + } + + for (i = 0; i < ncache_devices; i++) + write_sb(cache_devices[i], block_size, bucket_size, + writeback, discard, cache_replacement_policy, + data_offset, set_uuid, false); + + for (i = 0; i < nbacking_devices; i++) + write_sb(backing_devices[i], block_size, bucket_size, + writeback, discard, cache_replacement_policy, + data_offset, set_uuid, true); + return 0; }