DF-2633 / verify2633.c
/* * DF-2633 verifier - after remount, walk fill.bin and classify each 64KB * block against the deterministic generator (fillbuf(0xC0FFEE123456789 + * blockno)): OK / HOLE(all zero) / MISMATCH / EOF. Reports totals and the * list of first 40 lost blocks. Quantifies exactly which write()- * successful data vanished. */ #include <errno.h> #include <fcntl.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #define BLSZ 65536 #define MAXBLOCKS 8192 static uint64_t xs64(uint64_t *s) { uint64_t x = *s; x ^= x << 13; x ^= x >> 7; x ^= x << 17; *s = x; return x; } static void fillbuf(uint64_t seed, uint8_t *buf, size_t n) { size_t i; for (i = 0; i < n; i += 8) { uint64_t r = xs64(&seed); memcpy(buf + i, &r, (n - i >= 8) ? 8 : n - i); } } int main(int argc, char **argv) { const char *file; uint8_t *exp, *got; int fd, rc, i; long ok = 0, hole = 0, mism = 0, eof = 0, listed = 0; off_t off = 0; struct stat sb; if (argc != 2) { fprintf(stderr, "usage: %s <fill.bin>\n", argv[0]); return 2; } file = argv[1]; setvbuf(stdout, NULL, _IONBF, 0); fd = open(file, O_RDONLY); if (fd < 0) { perror(file); return 2; } if (fstat(fd, &sb) == 0) printf("VERIFY_SIZE %jd\n", (intmax_t)sb.st_size); exp = malloc(BLSZ); got = malloc(BLSZ); for (i = 0; i < MAXBLOCKS; ++i, off += BLSZ) { fillbuf(0xC0FFEE123456789ULL + i, exp, BLSZ); rc = read(fd, got, BLSZ); if (rc == 0) { eof = 1; break; } if (rc < 0) { printf("VERIFY_READ_ERR %d\n", errno); break; } if (rc < BLSZ) { /* short (tail) block: zero-pad compare */ memset(got + rc, 0, BLSZ - rc); memset(exp + rc, 0, BLSZ - rc); } { int z = 1, m = 0, k; for (k = 0; k < BLSZ; k += 8) { if (memcmp(got + k, exp + k, 8) != 0) { m = 1; } if (memcmp(got + k, "\0\0\0\0\0\0\0\0", 8) != 0) { z = 0; } } if (m == 0) ++ok; else if (z) ++hole; else ++mism; if (m && listed < 40) { printf("LOST_BLOCK idx=%d off=%jd class=%s\n", i, (intmax_t)off, z ? "hole" : "mismatch"); ++listed; } } } printf("VERIFY_DONE ok=%ld hole=%ld mismatch=%ld%s\n", ok, hole, mism, eof ? " eof" : ""); return 0; } |