diff options
author | Kent Overstreet <koverstreet@google.com> | 2012-11-21 15:31:49 -0800 |
---|---|---|
committer | Kent Overstreet <koverstreet@google.com> | 2012-11-21 15:31:49 -0800 |
commit | 133c859a24ad02931059681da60e9eeb43e30cb9 (patch) | |
tree | 864711405b1647995c031e13b26cf2533c7c3f94 | |
parent | f2a9bace3786cf58910c4a7b9d76d1117769ef7c (diff) | |
download | bcache-tools-133c859a24ad02931059681da60e9eeb43e30cb9.tar.gz |
Better validation, and use O_EXCL when opening block device
-rw-r--r-- | make-bcache.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/make-bcache.c b/make-bcache.c index bebe3a23..e20a7cf6 100644 --- a/make-bcache.c +++ b/make-bcache.c @@ -6,6 +6,7 @@ #include <errno.h> #include <fcntl.h> #include <getopt.h> +#include <limits.h> #include <linux/fs.h> #include <stdbool.h> #include <stdint.h> @@ -58,6 +59,30 @@ uint64_t hatoi(const char *s) return i; } +unsigned hatoi_validate(const char *s, const char *msg) +{ + uint64_t v = hatoi(s); + + if (v & (v - 1)) { + printf("%s must be a power of two\n", msg); + exit(EXIT_FAILURE); + } + + v /= 512; + + if (v > USHRT_MAX) { + printf("%s too large\n", msg); + exit(EXIT_FAILURE); + } + + if (!v) { + printf("%s too small\n", msg); + exit(EXIT_FAILURE); + } + + return v; +} + char *skip_spaces(const char *str) { while (isspace(*str)) @@ -154,18 +179,12 @@ void write_sb(char *dev, struct cache_sb *sb) usage(); } - if ((sb->bucket_size & (sb->bucket_size - 1)) || - (sb->block_size & (sb->block_size - 1))) { - printf("Block and bucket sizes must be powers of two\n"); - exit(EXIT_FAILURE); - } - if (sb->bucket_size < sb->block_size) { - printf("Bad bucket size %i\n", sb->bucket_size); + printf("Bucket size cannot be smaller than block size\n"); exit(EXIT_FAILURE); } - if ((fd = open(dev, O_RDWR)) == -1) { + if ((fd = open(dev, O_RDWR|O_EXCL)) == -1) { printf("Can't open dev %s: %s\n", dev, strerror(errno)); exit(EXIT_FAILURE); } @@ -252,10 +271,10 @@ int main(int argc, char **argv) sb.version = CACHE_BACKING_DEV; break; case 'b': - sb.bucket_size = hatoi(optarg) / 512; + sb.bucket_size = hatoi_validate(optarg, "bucket size"); break; case 'w': - sb.block_size = hatoi(optarg) / 512; + sb.block_size = hatoi_validate(optarg, "block size"); break; case 'U': if (uuid_parse(optarg, sb.uuid)) { |