diff --git a/bcache-test.c b/bcache-test.c index 33218e53..69a3c48b 100644 --- a/bcache-test.c +++ b/bcache-test.c @@ -71,8 +71,9 @@ long getblocks(int fd) int main(int argc, char **argv) { bool walk = false, randsize = false, verbose = false; - int fd1, fd2, direct = 0; - long size, i; + int fd1, fd2, direct = 0, nbytes = 4096, j; + unsigned long size, i = 0, offset = 0; + void *buf1 = NULL, *buf2 = NULL; if (argc < 3) { printf("Please enter a cache device and raw device\n"); @@ -82,12 +83,16 @@ int main(int argc, char **argv) for (i = 3; i < argc; i++) { if (strcmp(argv[i], "direct") == 0) direct = O_DIRECT; - if (strcmp(argv[i], "walk") == 0) + else if (strcmp(argv[i], "walk") == 0) walk = true; - if (strcmp(argv[i], "verbose") == 0) + else if (strcmp(argv[i], "verbose") == 0) verbose = true; - if (strcmp(argv[i], "size") == 0) + else if (strcmp(argv[i], "size") == 0) randsize = true; + else { + printf("Uknown argument %s\n", argv[i]); + exit(EXIT_FAILURE); + } } fd1 = open(argv[1], O_RDONLY|direct); @@ -97,29 +102,42 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - size = MIN(getblocks(fd1), getblocks(fd2)) / 8; + size = MIN(getblocks(fd1), getblocks(fd2)) / 8 - 16; printf("size %li\n", size); - for (i = 0;; i++) { - char buf1[4096 * 16], buf2[4096 * 16]; - long offset; - int pages = randsize ? MAX(MIN(abs(normal()) * 4, 16), 1) : 1; + if (posix_memalign(&buf1, 4096, 4096 * 16) || + posix_memalign(&buf2, 4096, 4096 * 16)) { + printf("Could not allocate buffers\n"); + exit(EXIT_FAILURE); + } - offset = walk ? offset * normal() * 2 : random(); + while (1) { + if (randsize) + nbytes = 4096 * (int) (drand48() * 16 + 1); + + offset += walk ? normal() * 60 : random(); offset %= size; + assert(offset < size); - if (verbose) - printf("Loop %li offset %li\n", i, offset); - else if (!(i % 100)) - printf("Loop %li\n", i); + do { + if (verbose) + printf("Loop %li offset %li sectors %i\n", + i, offset << 3, nbytes >> 9); + else if (!(i % 100)) + printf("Loop %li\n", i); - Pread(fd1, buf1, 4096 * pages, offset << 12); - Pread(fd2, buf2, 4096 * pages, offset << 12); + Pread(fd1, buf1, nbytes, offset << 12); + Pread(fd2, buf2, nbytes, offset << 12); - if (memcmp(buf1, buf2, 4096 * pages)) { - printf("Bad read! offset %li", offset << 12); - exit(EXIT_FAILURE); - } + for (j = 0; j < nbytes; j += 512) + if (memcmp(buf1 + j, + buf2 + j, + 512)) { + printf("Bad read! offset %li sectors %i, sector %i\n", + offset << 3, nbytes >> 9, j >> 9); + exit(EXIT_FAILURE); + } + } while (!(i++ & 1)); } err: perror("Read error"); diff --git a/make-bcache.c b/make-bcache.c index 54828bbc..38a4d436 100644 --- a/make-bcache.c +++ b/make-bcache.c @@ -1,3 +1,5 @@ +#define _FILE_OFFSET_BITS 64 +#define __USE_FILE_OFFSET64 #define _XOPEN_SOURCE 500 #include @@ -10,6 +12,7 @@ #include #include #include +#include static const char bcache_magic[] = { 0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca, @@ -34,47 +37,86 @@ struct bucket_disk { char zero[4096]; -int main(int argc, char **argv) +long getblocks(int fd) { - long n; - int fd, i; + long ret; struct stat statbuf; - struct cache_sb sb; - - if (argc < 2) { - printf("Please supply a device\n"); - exit(EXIT_FAILURE); - } - - fd = open(argv[1], O_RDWR); - if (!fd) { - perror("Can't open dev\n"); - exit(EXIT_FAILURE); - } - if (fstat(fd, &statbuf)) { perror("stat error\n"); exit(EXIT_FAILURE); } - if (!S_ISBLK(statbuf.st_mode)) - n = statbuf.st_blocks; - else - if (ioctl(fd, BLKGETSIZE, &n)) { + ret = statbuf.st_blocks; + if (S_ISBLK(statbuf.st_mode)) + if (ioctl(fd, BLKGETSIZE, &ret)) { perror("ioctl error"); exit(EXIT_FAILURE); } + return ret; +} + +long hatoi(const char *s) +{ + char *e; + long long i = strtol(s, &e, 10); + switch (*e) { + case 't': + case 'T': + i *= 1024; + case 'g': + case 'G': + i *= 1024; + case 'm': + case 'M': + i *= 1024; + case 'k': + case 'K': + i *= 1024; + } + return i; +} + +int main(int argc, char **argv) +{ + int64_t nblocks, bucketsize = 1024, blocksize = 8; + int fd, i, c; + struct cache_sb sb; + + while ((c = getopt(argc, argv, "b:")) != -1) { + switch (c) { + case 'b': + bucketsize = hatoi(optarg) / 512; + break; + } + } + + if (argc <= optind) { + printf("Please supply a device\n"); + exit(EXIT_FAILURE); + } + + fd = open(argv[optind], O_RDWR); + if (fd == -1) { + perror("Can't open dev\n"); + exit(EXIT_FAILURE); + } + nblocks = getblocks(fd); + + if (bucketsize < blocksize || + bucketsize > nblocks / 8) { + printf("Bad bucket size %li\n", bucketsize); + exit(EXIT_FAILURE); + } memcpy(sb.magic, bcache_magic, 16); sb.version = 0; - sb.block_size = 8; - sb.bucket_size = 32; - sb.nbuckets = n / sb.bucket_size; + sb.block_size = blocksize; + sb.bucket_size = bucketsize; + sb.nbuckets = nblocks / sb.bucket_size; do sb.first_bucket = ((--sb.nbuckets * sizeof(struct bucket_disk)) + 4096 * 3) / (sb.bucket_size * 512) + 1; - while ((sb.nbuckets + sb.first_bucket) * sb.bucket_size * 512 - > statbuf.st_size); + while ((sb.nbuckets + sb.first_bucket) * sb.bucket_size > nblocks); sb.journal_start = sb.first_bucket;