gfio: add gerror.c for reporting errors
[fio.git] / verify.c
index 9ee3bc42ca215961b03951445fdb64070b3f35aa..f25eab921fc379691466b9e8c3866efd3a2133eb 100644 (file)
--- a/verify.c
+++ b/verify.c
@@ -78,7 +78,7 @@ static unsigned int get_hdr_inc(struct thread_data *td, struct io_u *io_u)
        unsigned int hdr_inc;
 
        hdr_inc = io_u->buflen;
-       if (td->o.verify_interval)
+       if (td->o.verify_interval && td->o.verify_interval <= io_u->buflen)
                hdr_inc = td->o.verify_interval;
 
        return hdr_inc;
@@ -322,14 +322,27 @@ static int verify_io_u_pattern(struct verify_header *hdr, struct vcont *vc)
        struct io_u *io_u = vc->io_u;
        char *buf, *pattern;
        unsigned int header_size = __hdr_size(td->o.verify);
-       unsigned int len, mod, i;
+       unsigned int len, mod, i, size, pattern_size;
 
        pattern = td->o.verify_pattern;
+       pattern_size = td->o.verify_pattern_bytes;
+       if (pattern_size <= 1)
+               pattern_size = MAX_PATTERN_SIZE;
        buf = (void *) hdr + header_size;
        len = get_hdr_inc(td, io_u) - header_size;
-       mod = header_size % td->o.verify_pattern_bytes;
+       mod = header_size % pattern_size;
+
+       for (i = 0; i < len; i += size) {
+               size = pattern_size - mod;
+               if (size > (len - i))
+                       size = len - i;
+               if (memcmp(buf + i, pattern + mod, size))
+                       /* Let the slow compare find the first mismatch byte. */
+                       break;
+               mod = 0;
+       }
 
-       for (i = 0; i < len; i++) {
+       for (; i < len; i++) {
                if (buf[i] != pattern[mod]) {
                        unsigned int bits;
 
@@ -376,14 +389,14 @@ static int verify_io_u_sha512(struct verify_header *hdr, struct vcont *vc)
        void *p = io_u_verify_off(hdr, vc);
        struct vhdr_sha512 *vh = hdr_priv(hdr);
        uint8_t sha512[128];
-       struct sha512_ctx sha512_ctx = {
+       struct fio_sha512_ctx sha512_ctx = {
                .buf = sha512,
        };
 
        dprint(FD_VERIFY, "sha512 verify io_u %p, len %u\n", vc->io_u, hdr->len);
 
-       sha512_init(&sha512_ctx);
-       sha512_update(&sha512_ctx, p, hdr->len - hdr_size(hdr));
+       fio_sha512_init(&sha512_ctx);
+       fio_sha512_update(&sha512_ctx, p, hdr->len - hdr_size(hdr));
 
        if (!memcmp(vh->sha512, sha512_ctx.buf, sizeof(sha512)))
                return 0;
@@ -401,14 +414,14 @@ static int verify_io_u_sha256(struct verify_header *hdr, struct vcont *vc)
        void *p = io_u_verify_off(hdr, vc);
        struct vhdr_sha256 *vh = hdr_priv(hdr);
        uint8_t sha256[64];
-       struct sha256_ctx sha256_ctx = {
+       struct fio_sha256_ctx sha256_ctx = {
                .buf = sha256,
        };
 
        dprint(FD_VERIFY, "sha256 verify io_u %p, len %u\n", vc->io_u, hdr->len);
 
-       sha256_init(&sha256_ctx);
-       sha256_update(&sha256_ctx, p, hdr->len - hdr_size(hdr));
+       fio_sha256_init(&sha256_ctx);
+       fio_sha256_update(&sha256_ctx, p, hdr->len - hdr_size(hdr));
 
        if (!memcmp(vh->sha256, sha256_ctx.buf, sizeof(sha256)))
                return 0;
@@ -426,14 +439,14 @@ static int verify_io_u_sha1(struct verify_header *hdr, struct vcont *vc)
        void *p = io_u_verify_off(hdr, vc);
        struct vhdr_sha1 *vh = hdr_priv(hdr);
        uint32_t sha1[5];
-       struct sha1_ctx sha1_ctx = {
+       struct fio_sha1_ctx sha1_ctx = {
                .H = sha1,
        };
 
        dprint(FD_VERIFY, "sha1 verify io_u %p, len %u\n", vc->io_u, hdr->len);
 
-       sha1_init(&sha1_ctx);
-       sha1_update(&sha1_ctx, p, hdr->len - hdr_size(hdr));
+       fio_sha1_init(&sha1_ctx);
+       fio_sha1_update(&sha1_ctx, p, hdr->len - hdr_size(hdr));
 
        if (!memcmp(vh->sha1, sha1_ctx.H, sizeof(sha1)))
                return 0;
@@ -454,7 +467,7 @@ static int verify_io_u_crc7(struct verify_header *hdr, struct vcont *vc)
 
        dprint(FD_VERIFY, "crc7 verify io_u %p, len %u\n", vc->io_u, hdr->len);
 
-       c = crc7(p, hdr->len - hdr_size(hdr));
+       c = fio_crc7(p, hdr->len - hdr_size(hdr));
 
        if (c == vh->crc7)
                return 0;
@@ -475,7 +488,7 @@ static int verify_io_u_crc16(struct verify_header *hdr, struct vcont *vc)
 
        dprint(FD_VERIFY, "crc16 verify io_u %p, len %u\n", vc->io_u, hdr->len);
 
-       c = crc16(p, hdr->len - hdr_size(hdr));
+       c = fio_crc16(p, hdr->len - hdr_size(hdr));
 
        if (c == vh->crc16)
                return 0;
@@ -496,7 +509,7 @@ static int verify_io_u_crc64(struct verify_header *hdr, struct vcont *vc)
 
        dprint(FD_VERIFY, "crc64 verify io_u %p, len %u\n", vc->io_u, hdr->len);
 
-       c = crc64(p, hdr->len - hdr_size(hdr));
+       c = fio_crc64(p, hdr->len - hdr_size(hdr));
 
        if (c == vh->crc64)
                return 0;
@@ -517,7 +530,7 @@ static int verify_io_u_crc32(struct verify_header *hdr, struct vcont *vc)
 
        dprint(FD_VERIFY, "crc32 verify io_u %p, len %u\n", vc->io_u, hdr->len);
 
-       c = crc32(p, hdr->len - hdr_size(hdr));
+       c = fio_crc32(p, hdr->len - hdr_size(hdr));
 
        if (c == vh->crc32)
                return 0;
@@ -538,10 +551,7 @@ static int verify_io_u_crc32c(struct verify_header *hdr, struct vcont *vc)
 
        dprint(FD_VERIFY, "crc32c verify io_u %p, len %u\n", vc->io_u, hdr->len);
 
-       if (hdr->verify_type == VERIFY_CRC32C_INTEL)
-               c = crc32c_intel(p, hdr->len - hdr_size(hdr));
-       else
-               c = crc32c(p, hdr->len - hdr_size(hdr));
+       c = fio_crc32c(p, hdr->len - hdr_size(hdr));
 
        if (c == vh->crc32)
                return 0;
@@ -559,14 +569,14 @@ static int verify_io_u_md5(struct verify_header *hdr, struct vcont *vc)
        void *p = io_u_verify_off(hdr, vc);
        struct vhdr_md5 *vh = hdr_priv(hdr);
        uint32_t hash[MD5_HASH_WORDS];
-       struct md5_ctx md5_ctx = {
+       struct fio_md5_ctx md5_ctx = {
                .hash = hash,
        };
 
        dprint(FD_VERIFY, "md5 verify io_u %p, len %u\n", vc->io_u, hdr->len);
 
-       md5_init(&md5_ctx);
-       md5_update(&md5_ctx, p, hdr->len - hdr_size(hdr));
+       fio_md5_init(&md5_ctx);
+       fio_md5_update(&md5_ctx, p, hdr->len - hdr_size(hdr));
 
        if (!memcmp(vh->md5_digest, md5_ctx.hash, sizeof(hash)))
                return 0;
@@ -636,6 +646,26 @@ static int verify_trimmed_io_u(struct thread_data *td, struct io_u *io_u)
        return ret;
 }
 
+static int verify_header(struct io_u *io_u, struct verify_header *hdr)
+{
+       void *p = hdr;
+       uint32_t crc;
+
+       if (hdr->magic != FIO_HDR_MAGIC)
+               return 0;
+       if (hdr->len > io_u->buflen) {
+               log_err("fio: verify header exceeds buffer length (%u > %lu)\n", hdr->len, io_u->buflen);
+               return 0;
+       }
+
+       crc = fio_crc32c(p, offsetof(struct verify_header, crc32));
+       if (crc == hdr->crc32)
+               return 1;
+
+       log_err("fio: verify header crc %x, calculated %x\n", hdr->crc32, crc);
+       return 0;
+}
+
 int verify_io_u(struct thread_data *td, struct io_u *io_u)
 {
        struct verify_header *hdr;
@@ -669,9 +699,10 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u)
                        memswp(p, p + td->o.verify_offset, header_size);
                hdr = p;
 
-               if (hdr->fio_magic != FIO_HDR_MAGIC) {
-                       log_err("verify: bad magic header %x, wanted %x at file %s offset %llu, length %u\n",
-                               hdr->fio_magic, FIO_HDR_MAGIC,
+               if (!verify_header(io_u, hdr)) {
+                       log_err("verify: bad magic header %x, wanted %x at "
+                               "file %s offset %llu, length %u\n",
+                               hdr->magic, FIO_HDR_MAGIC,
                                io_u->file->file_name,
                                io_u->offset + hdr_num * hdr->len, hdr->len);
                        return EILSEQ;
@@ -743,83 +774,80 @@ static void fill_meta(struct verify_header *hdr, struct thread_data *td,
 static void fill_sha512(struct verify_header *hdr, void *p, unsigned int len)
 {
        struct vhdr_sha512 *vh = hdr_priv(hdr);
-       struct sha512_ctx sha512_ctx = {
+       struct fio_sha512_ctx sha512_ctx = {
                .buf = vh->sha512,
        };
 
-       sha512_init(&sha512_ctx);
-       sha512_update(&sha512_ctx, p, len);
+       fio_sha512_init(&sha512_ctx);
+       fio_sha512_update(&sha512_ctx, p, len);
 }
 
 static void fill_sha256(struct verify_header *hdr, void *p, unsigned int len)
 {
        struct vhdr_sha256 *vh = hdr_priv(hdr);
-       struct sha256_ctx sha256_ctx = {
+       struct fio_sha256_ctx sha256_ctx = {
                .buf = vh->sha256,
        };
 
-       sha256_init(&sha256_ctx);
-       sha256_update(&sha256_ctx, p, len);
+       fio_sha256_init(&sha256_ctx);
+       fio_sha256_update(&sha256_ctx, p, len);
 }
 
 static void fill_sha1(struct verify_header *hdr, void *p, unsigned int len)
 {
        struct vhdr_sha1 *vh = hdr_priv(hdr);
-       struct sha1_ctx sha1_ctx = {
+       struct fio_sha1_ctx sha1_ctx = {
                .H = vh->sha1,
        };
 
-       sha1_init(&sha1_ctx);
-       sha1_update(&sha1_ctx, p, len);
+       fio_sha1_init(&sha1_ctx);
+       fio_sha1_update(&sha1_ctx, p, len);
 }
 
 static void fill_crc7(struct verify_header *hdr, void *p, unsigned int len)
 {
        struct vhdr_crc7 *vh = hdr_priv(hdr);
 
-       vh->crc7 = crc7(p, len);
+       vh->crc7 = fio_crc7(p, len);
 }
 
 static void fill_crc16(struct verify_header *hdr, void *p, unsigned int len)
 {
        struct vhdr_crc16 *vh = hdr_priv(hdr);
 
-       vh->crc16 = crc16(p, len);
+       vh->crc16 = fio_crc16(p, len);
 }
 
 static void fill_crc32(struct verify_header *hdr, void *p, unsigned int len)
 {
        struct vhdr_crc32 *vh = hdr_priv(hdr);
 
-       vh->crc32 = crc32(p, len);
+       vh->crc32 = fio_crc32(p, len);
 }
 
 static void fill_crc32c(struct verify_header *hdr, void *p, unsigned int len)
 {
        struct vhdr_crc32 *vh = hdr_priv(hdr);
 
-       if (hdr->verify_type == VERIFY_CRC32C_INTEL)
-               vh->crc32 = crc32c_intel(p, len);
-       else
-               vh->crc32 = crc32c(p, len);
+       vh->crc32 = fio_crc32c(p, len);
 }
 
 static void fill_crc64(struct verify_header *hdr, void *p, unsigned int len)
 {
        struct vhdr_crc64 *vh = hdr_priv(hdr);
 
-       vh->crc64 = crc64(p, len);
+       vh->crc64 = fio_crc64(p, len);
 }
 
 static void fill_md5(struct verify_header *hdr, void *p, unsigned int len)
 {
        struct vhdr_md5 *vh = hdr_priv(hdr);
-       struct md5_ctx md5_ctx = {
+       struct fio_md5_ctx md5_ctx = {
                .hash = (uint32_t *) vh->md5_digest,
        };
 
-       md5_init(&md5_ctx);
-       md5_update(&md5_ctx, p, len);
+       fio_md5_init(&md5_ctx);
+       fio_md5_update(&md5_ctx, p, len);
 }
 
 static void populate_hdr(struct thread_data *td, struct io_u *io_u,
@@ -831,10 +859,12 @@ static void populate_hdr(struct thread_data *td, struct io_u *io_u,
 
        p = (void *) hdr;
 
-       hdr->fio_magic = FIO_HDR_MAGIC;
-       hdr->len = header_len;
+       hdr->magic = FIO_HDR_MAGIC;
        hdr->verify_type = td->o.verify;
+       hdr->len = header_len;
        hdr->rand_seed = io_u->rand_seed;
+       hdr->crc32 = fio_crc32c(p, offsetof(struct verify_header, crc32));
+
        data_len = header_len - hdr_size(hdr);
 
        data = p + hdr_size(hdr);
@@ -943,6 +973,7 @@ int get_next_verify(struct thread_data *td, struct io_u *io_u)
                io_u->offset = ipo->offset;
                io_u->buflen = ipo->len;
                io_u->file = ipo->file;
+               io_u->flags |= IO_U_F_VER_LIST;
 
                if (ipo->flags & IP_F_TRIMMED)
                        io_u->flags |= IO_U_F_TRIMMED;