From 11a1a3ca520aa3bfbb45b0d41b3336fef51844f0 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Fri, 14 May 2010 08:54:26 -0800 Subject: [PATCH] Checksum test --- bcache-test.c | 91 +++++++++++++++++++++++++++++++++++++-------------- make-bcache.c | 8 ++--- 2 files changed, 70 insertions(+), 29 deletions(-) diff --git a/bcache-test.c b/bcache-test.c index 69a3c48..49bb723 100644 --- a/bcache-test.c +++ b/bcache-test.c @@ -15,6 +15,7 @@ #include #include #include +#include #define Pread(fd, buf, size, offset) do { \ int _read = 0, _r; \ @@ -51,15 +52,35 @@ double normal() return x * s; } +uint32_t fletcher32(uint16_t *data, size_t len) +{ + uint32_t sum1 = 0xffff, sum2 = 0xffff; + + while (len) { + unsigned tlen = len > 360 ? 360 : len; + len -= tlen; + do { + sum1 += *data++; + sum2 += sum1; + } while (--tlen); + sum1 = (sum1 & 0xffff) + (sum1 >> 16); + sum2 = (sum2 & 0xffff) + (sum2 >> 16); + } + /* Second reduction step to reduce sums to 16 bits */ + sum1 = (sum1 & 0xffff) + (sum1 >> 16); + sum2 = (sum2 & 0xffff) + (sum2 >> 16); + return sum2 << 16 | sum1; +} + long getblocks(int fd) { long ret; struct stat statbuf; if (fstat(fd, &statbuf)) { - perror("stat error\n"); + perror("stat error"); exit(EXIT_FAILURE); } - ret = statbuf.st_blocks; + ret = statbuf.st_size / 512; if (S_ISBLK(statbuf.st_mode)) if (ioctl(fd, BLKGETSIZE, &ret)) { perror("ioctl error"); @@ -70,17 +91,18 @@ long getblocks(int fd) int main(int argc, char **argv) { - bool walk = false, randsize = false, verbose = false; - int fd1, fd2, direct = 0, nbytes = 4096, j; - unsigned long size, i = 0, offset = 0; + bool walk = false, randsize = false, verbose = false, csum = false; + int fd1, fd2 = 0, direct = 0, nbytes = 4096, j; + unsigned long size, i, offset = 0; void *buf1 = NULL, *buf2 = NULL; + uint32_t *csums = NULL; if (argc < 3) { printf("Please enter a cache device and raw device\n"); exit(EXIT_FAILURE); } - for (i = 3; i < argc; i++) { + for (i = 1; i < argc; i++) { if (strcmp(argv[i], "direct") == 0) direct = O_DIRECT; else if (strcmp(argv[i], "walk") == 0) @@ -89,20 +111,27 @@ int main(int argc, char **argv) verbose = true; else if (strcmp(argv[i], "size") == 0) randsize = true; - else { - printf("Uknown argument %s\n", argv[i]); - exit(EXIT_FAILURE); - } + else if (strcmp(argv[i], "csum") == 0) + csum= true; + else + break; } - fd1 = open(argv[1], O_RDONLY|direct); - fd2 = open(argv[2], O_RDONLY|direct); + fd1 = open(argv[i], O_RDONLY|direct); + size = getblocks(fd1); + + if (!csum) { + fd2 = open(argv[2], O_RDONLY|direct); + size = MIN(size, getblocks(fd2)); + } else + csums = calloc((size / 8 + 1), sizeof(*csums)); + if (fd1 == -1 || fd2 == -1) { perror("Error opening device"); exit(EXIT_FAILURE); } - size = MIN(getblocks(fd1), getblocks(fd2)) / 8 - 16; + size = size / 8 - 16; printf("size %li\n", size); if (posix_memalign(&buf1, 4096, 4096 * 16) || @@ -110,34 +139,46 @@ int main(int argc, char **argv) printf("Could not allocate buffers\n"); exit(EXIT_FAILURE); } + setvbuf(stdout, NULL, _IONBF, 0); - while (1) { + for (i = 0;; i++) { if (randsize) nbytes = 4096 * (int) (drand48() * 16 + 1); - offset += walk ? normal() * 60 : random(); + offset += walk ? normal() * 100 : random(); offset %= size; assert(offset < size); - 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); + 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, nbytes, offset << 12); - Pread(fd1, buf1, nbytes, offset << 12); + if (!csum) { Pread(fd2, buf2, nbytes, offset << 12); 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); + printf("Bad read! loop %li offset %li sectors %i, sector %i\n", + i, offset << 3, nbytes >> 9, j >> 9); + exit(EXIT_FAILURE); + } + } else + for (j = 0; j < nbytes / 4096; j++) { + int c = fletcher32(buf1 + j * 4096, 4096); + if (!csums[offset + j]) + csums[offset + j] = c; + else if (csums[offset + j] != c) { + printf("Bad read! loop %li offset %li sectors %i, sector %i\n", + i, offset << 3, nbytes >> 9, j << 3); exit(EXIT_FAILURE); } - } while (!(i++ & 1)); + } } err: perror("Read error"); diff --git a/make-bcache.c b/make-bcache.c index 38a4d43..7bf10b0 100644 --- a/make-bcache.c +++ b/make-bcache.c @@ -45,7 +45,7 @@ long getblocks(int fd) perror("stat error\n"); exit(EXIT_FAILURE); } - ret = statbuf.st_blocks; + ret = statbuf.st_size / 512; if (S_ISBLK(statbuf.st_mode)) if (ioctl(fd, BLKGETSIZE, &ret)) { perror("ioctl error"); @@ -77,7 +77,7 @@ long hatoi(const char *s) int main(int argc, char **argv) { - int64_t nblocks, bucketsize = 1024, blocksize = 8; + int64_t nblocks, bucketsize = 32, blocksize = 8; int fd, i, c; struct cache_sb sb; @@ -100,6 +100,7 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } nblocks = getblocks(fd); + printf("device is %li sectors\n", nblocks); if (bucketsize < blocksize || bucketsize > nblocks / 8) { @@ -114,8 +115,7 @@ int main(int argc, char **argv) sb.nbuckets = nblocks / sb.bucket_size; do - sb.first_bucket = ((--sb.nbuckets * sizeof(struct bucket_disk)) - + 4096 * 3) / (sb.bucket_size * 512) + 1; + sb.first_bucket = ((--sb.nbuckets * sizeof(struct bucket_disk)) + (24 << 9)) / (sb.bucket_size << 9) + 1; while ((sb.nbuckets + sb.first_bucket) * sb.bucket_size > nblocks); sb.journal_start = sb.first_bucket; -- 2.39.2