mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-23 00:00:02 +03:00
Write testing, fixed checksumming
This commit is contained in:
parent
d43ecc82a6
commit
bbe6fe14d2
4
Makefile
4
Makefile
@ -4,6 +4,6 @@ CFLAGS=-O2 -Wall -g
|
|||||||
all: make-bcache bcache-test
|
all: make-bcache bcache-test
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f make-bcache bcache-test
|
rm -f make-bcache bcache-test *.o
|
||||||
|
|
||||||
bcache-test: CFLAGS += -lm
|
bcache-test: LDFLAGS += -lm -lssl
|
||||||
|
138
bcache-test.c
138
bcache-test.c
@ -1,7 +1,6 @@
|
|||||||
#define _XOPEN_SOURCE 500
|
#define _XOPEN_SOURCE 500
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
@ -17,6 +16,15 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <openssl/rc4.h>
|
||||||
|
#include <openssl/md4.h>
|
||||||
|
|
||||||
|
static const unsigned char bcache_magic[] = {
|
||||||
|
0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca,
|
||||||
|
0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81 };
|
||||||
|
|
||||||
|
unsigned char zero[4096];
|
||||||
|
|
||||||
#define Pread(fd, buf, size, offset) do { \
|
#define Pread(fd, buf, size, offset) do { \
|
||||||
int _read = 0, _r; \
|
int _read = 0, _r; \
|
||||||
while (_read < size) { \
|
while (_read < size) { \
|
||||||
@ -27,6 +35,16 @@
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define Pwrite(fd, buf, size, offset) do { \
|
||||||
|
int _write = 0, _r; \
|
||||||
|
while (_write < size) { \
|
||||||
|
_r = pwrite(fd, buf, (size) - _write, offset + _write); \
|
||||||
|
if (_r < 0) \
|
||||||
|
goto err; \
|
||||||
|
_write += _r; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* Marsaglia polar method
|
/* Marsaglia polar method
|
||||||
*/
|
*/
|
||||||
double normal()
|
double normal()
|
||||||
@ -52,26 +70,6 @@ double normal()
|
|||||||
return x * s;
|
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 getblocks(int fd)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
@ -91,16 +89,14 @@ long getblocks(int fd)
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool walk = false, randsize = false, verbose = false, csum = false;
|
bool walk = false, randsize = false, verbose = false, csum = false, destructive = false;
|
||||||
int fd1, fd2 = 0, direct = 0, nbytes = 4096, j;
|
int fd1, fd2 = 0, direct = 0, nbytes = 4096, j;
|
||||||
unsigned long size, i, offset = 0;
|
unsigned long size, i, offset = 0;
|
||||||
void *buf1 = NULL, *buf2 = NULL;
|
void *buf1 = NULL, *buf2 = NULL;
|
||||||
uint32_t *csums = NULL;
|
uint64_t *csums = NULL, *cp, c[2];
|
||||||
|
|
||||||
if (argc < 3) {
|
RC4_KEY writedata;
|
||||||
printf("Please enter a cache device and raw device\n");
|
RC4_set_key(&writedata, 16, bcache_magic);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
if (strcmp(argv[i], "direct") == 0)
|
if (strcmp(argv[i], "direct") == 0)
|
||||||
@ -113,25 +109,37 @@ int main(int argc, char **argv)
|
|||||||
randsize = true;
|
randsize = true;
|
||||||
else if (strcmp(argv[i], "csum") == 0)
|
else if (strcmp(argv[i], "csum") == 0)
|
||||||
csum = true;
|
csum = true;
|
||||||
|
else if (strcmp(argv[i], "write") == 0)
|
||||||
|
destructive = true;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd1 = open(argv[i], O_RDONLY|direct);
|
if (i + 1 > argc) {
|
||||||
size = getblocks(fd1);
|
printf("Please enter a device to test\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
if (!csum) {
|
if (i + 2 > argc && !csum) {
|
||||||
fd2 = open(argv[2], O_RDONLY|direct);
|
printf("Please enter a device to compare against\n");
|
||||||
size = MIN(size, getblocks(fd2));
|
exit(EXIT_FAILURE);
|
||||||
} else
|
}
|
||||||
csums = calloc((size / 8 + 1), sizeof(*csums));
|
|
||||||
|
fd1 = open(argv[i], (destructive ? O_RDWR : O_RDONLY)|direct);
|
||||||
|
if (!csum)
|
||||||
|
fd2 = open(argv[i + 1], (destructive ? O_RDWR : O_RDONLY)|direct);
|
||||||
|
|
||||||
if (fd1 == -1 || fd2 == -1) {
|
if (fd1 == -1 || fd2 == -1) {
|
||||||
perror("Error opening device");
|
perror("Error opening device");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size = getblocks(fd1);
|
||||||
|
if (!csum)
|
||||||
|
size = MIN(size, getblocks(fd2));
|
||||||
|
|
||||||
size = size / 8 - 16;
|
size = size / 8 - 16;
|
||||||
|
csums = calloc(size + 16, sizeof(*csums));
|
||||||
printf("size %li\n", size);
|
printf("size %li\n", size);
|
||||||
|
|
||||||
if (posix_memalign(&buf1, 4096, 4096 * 16) ||
|
if (posix_memalign(&buf1, 4096, 4096 * 16) ||
|
||||||
@ -142,45 +150,51 @@ int main(int argc, char **argv)
|
|||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
|
|
||||||
for (i = 0;; i++) {
|
for (i = 0;; i++) {
|
||||||
if (randsize)
|
bool writing = destructive && (i & 1);
|
||||||
nbytes = 4096 * (int) (drand48() * 16 + 1);
|
nbytes = randsize ? drand48() * 16 + 1 : 1;
|
||||||
|
nbytes <<= 12;
|
||||||
|
|
||||||
offset += walk ? normal() * 100 : random();
|
offset += walk ? normal() * 100 : random();
|
||||||
offset %= size;
|
offset %= size;
|
||||||
assert(offset < size);
|
offset <<= 12;
|
||||||
|
|
||||||
if (verbose)
|
if (verbose || !(i % 100))
|
||||||
printf("Loop %li offset %li sectors %i\n",
|
printf("Loop %li offset %li sectors %i\n",
|
||||||
i, offset << 3, nbytes >> 9);
|
i, offset >> 9, nbytes >> 9);
|
||||||
else if (!(i % 100))
|
|
||||||
printf("Loop %li\n", i);
|
|
||||||
|
|
||||||
Pread(fd1, buf1, nbytes, offset << 12);
|
if (!writing)
|
||||||
|
Pread(fd1, buf1, nbytes, offset);
|
||||||
|
if (!writing && !csum)
|
||||||
|
Pread(fd2, buf2, nbytes, offset);
|
||||||
|
|
||||||
if (!csum) {
|
for (j = 0; j < nbytes; j += 4096) {
|
||||||
Pread(fd2, buf2, nbytes, offset << 12);
|
if (writing)
|
||||||
|
RC4(&writedata, 4096, zero, buf1 + j);
|
||||||
|
|
||||||
for (j = 0; j < nbytes; j += 512)
|
if (csum) {
|
||||||
if (memcmp(buf1 + j,
|
MD4(buf1 + j, 4096, (void*) c);
|
||||||
|
cp = csums + (offset + j) / 4096;
|
||||||
|
|
||||||
|
if (writing || !*cp)
|
||||||
|
*cp = c[0];
|
||||||
|
else if (*cp != c[0])
|
||||||
|
goto bad;
|
||||||
|
} else if (!writing &&
|
||||||
|
memcmp(buf1 + j,
|
||||||
buf2 + j,
|
buf2 + j,
|
||||||
512)) {
|
4096))
|
||||||
printf("Bad read! loop %li offset %li sectors %i, sector %i\n",
|
goto bad;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (writing)
|
||||||
|
Pwrite(fd1, buf1, nbytes, offset);
|
||||||
|
if (writing && !csum)
|
||||||
|
Pwrite(fd2, buf2, nbytes, offset);
|
||||||
}
|
}
|
||||||
err:
|
err:
|
||||||
perror("Read error");
|
perror("IO error");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
bad:
|
||||||
|
printf("Bad read! loop %li offset %li sectors %i, sector %i\n",
|
||||||
|
i, offset >> 9, nbytes >> 9, j >> 9);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user