Make sure that pattern verifies also dump contents
[fio.git] / verify.c
1 /*
2  * IO verification helpers
3  */
4 #include <unistd.h>
5 #include <fcntl.h>
6 #include <string.h>
7 #include <assert.h>
8 #include <pthread.h>
9 #include <libgen.h>
10
11 #include "fio.h"
12 #include "verify.h"
13 #include "smalloc.h"
14 #include "trim.h"
15 #include "lib/rand.h"
16
17 #include "crc/md5.h"
18 #include "crc/crc64.h"
19 #include "crc/crc32.h"
20 #include "crc/crc32c.h"
21 #include "crc/crc16.h"
22 #include "crc/crc7.h"
23 #include "crc/sha256.h"
24 #include "crc/sha512.h"
25 #include "crc/sha1.h"
26
27 static void populate_hdr(struct thread_data *td, struct io_u *io_u,
28                          struct verify_header *hdr, unsigned int header_num,
29                          unsigned int header_len);
30
31 void fill_pattern(struct thread_data *td, void *p, unsigned int len, struct io_u *io_u, unsigned long seed, int use_seed)
32 {
33         switch (td->o.verify_pattern_bytes) {
34         case 0:
35                 dprint(FD_VERIFY, "fill random bytes len=%u\n", len);
36                 if (use_seed)
37                         __fill_random_buf(p, len, seed);
38                 else
39                         io_u->rand_seed = fill_random_buf(p, len);
40                 break;
41         case 1:
42                 if (io_u->buf_filled_len >= len) {
43                         dprint(FD_VERIFY, "using already filled verify pattern b=0 len=%u\n", len);
44                         return;
45                 }
46                 dprint(FD_VERIFY, "fill verify pattern b=0 len=%u\n", len);
47                 memset(p, td->o.verify_pattern[0], len);
48                 io_u->buf_filled_len = len;
49                 break;
50         default: {
51                 unsigned int i = 0, size = 0;
52                 unsigned char *b = p;
53
54                 if (io_u->buf_filled_len >= len) {
55                         dprint(FD_VERIFY, "using already filled verify pattern b=%d len=%u\n",
56                                         td->o.verify_pattern_bytes, len);
57                         return;
58                 }
59                 dprint(FD_VERIFY, "fill verify pattern b=%d len=%u\n",
60                                         td->o.verify_pattern_bytes, len);
61
62                 while (i < len) {
63                         size = td->o.verify_pattern_bytes;
64                         if (size > (len - i))
65                                 size = len - i;
66                         memcpy(b+i, td->o.verify_pattern, size);
67                         i += size;
68                 }
69                 io_u->buf_filled_len = len;
70                 break;
71                 }
72         }
73 }
74
75 static unsigned int get_hdr_inc(struct thread_data *td, struct io_u *io_u)
76 {
77         unsigned int hdr_inc;
78
79         hdr_inc = io_u->buflen;
80         if (td->o.verify_interval)
81                 hdr_inc = td->o.verify_interval;
82
83         return hdr_inc;
84 }
85
86 static void fill_pattern_headers(struct thread_data *td, struct io_u *io_u,
87                                  unsigned long seed, int use_seed)
88 {
89         unsigned int hdr_inc, header_num;
90         struct verify_header *hdr;
91         void *p = io_u->buf;
92
93         fill_pattern(td, p, io_u->buflen, io_u, seed, use_seed);
94
95         hdr_inc = get_hdr_inc(td, io_u);
96         header_num = 0;
97         for (; p < io_u->buf + io_u->buflen; p += hdr_inc) {
98                 hdr = p;
99                 populate_hdr(td, io_u, hdr, header_num, hdr_inc);
100                 header_num++;
101         }
102 }
103
104 static void memswp(void *buf1, void *buf2, unsigned int len)
105 {
106         char swap[200];
107
108         assert(len <= sizeof(swap));
109
110         memcpy(&swap, buf1, len);
111         memcpy(buf1, buf2, len);
112         memcpy(buf2, &swap, len);
113 }
114
115 static void hexdump(void *buffer, int len)
116 {
117         unsigned char *p = buffer;
118         int i;
119
120         for (i = 0; i < len; i++)
121                 log_err("%02x", p[i]);
122         log_err("\n");
123 }
124
125 /*
126  * Prepare for seperation of verify_header and checksum header
127  */
128 static inline unsigned int __hdr_size(int verify_type)
129 {
130         unsigned int len = 0;
131
132         switch (verify_type) {
133         case VERIFY_NONE:
134         case VERIFY_NULL:
135                 len = 0;
136                 break;
137         case VERIFY_MD5:
138                 len = sizeof(struct vhdr_md5);
139                 break;
140         case VERIFY_CRC64:
141                 len = sizeof(struct vhdr_crc64);
142                 break;
143         case VERIFY_CRC32C:
144         case VERIFY_CRC32:
145         case VERIFY_CRC32C_INTEL:
146                 len = sizeof(struct vhdr_crc32);
147                 break;
148         case VERIFY_CRC16:
149                 len = sizeof(struct vhdr_crc16);
150                 break;
151         case VERIFY_CRC7:
152                 len = sizeof(struct vhdr_crc7);
153                 break;
154         case VERIFY_SHA256:
155                 len = sizeof(struct vhdr_sha256);
156                 break;
157         case VERIFY_SHA512:
158                 len = sizeof(struct vhdr_sha512);
159                 break;
160         case VERIFY_META:
161                 len = sizeof(struct vhdr_meta);
162                 break;
163         case VERIFY_SHA1:
164                 len = sizeof(struct vhdr_sha1);
165                 break;
166         default:
167                 log_err("fio: unknown verify header!\n");
168                 assert(0);
169         }
170
171         return len + sizeof(struct verify_header);
172 }
173
174 static inline unsigned int hdr_size(struct verify_header *hdr)
175 {
176         return __hdr_size(hdr->verify_type);
177 }
178
179 static void *hdr_priv(struct verify_header *hdr)
180 {
181         void *priv = hdr;
182
183         return priv + sizeof(struct verify_header);
184 }
185
186 /*
187  * Verify container, pass info to verify handlers and allow them to
188  * pass info back in case of error
189  */
190 struct vcont {
191         /*
192          * Input
193          */
194         struct io_u *io_u;
195         unsigned int hdr_num;
196         struct thread_data *td;
197
198         /*
199          * Output, only valid in case of error
200          */
201         const char *name;
202         void *good_crc;
203         void *bad_crc;
204         unsigned int crc_len;
205 };
206
207 static void dump_buf(char *buf, unsigned int len, unsigned long long offset,
208                      const char *type, struct fio_file *f)
209 {
210         char *ptr, fname[256];
211         int ret, fd;
212
213         ptr = strdup(f->file_name);
214         strcpy(fname, basename(ptr));
215
216         sprintf(fname + strlen(fname), ".%llu.%s", offset, type);
217
218         fd = open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0644);
219         if (fd < 0) {
220                 perror("open verify buf file");
221                 return;
222         }
223
224         while (len) {
225                 ret = write(fd, buf, len);
226                 if (!ret)
227                         break;
228                 else if (ret < 0) {
229                         perror("write verify buf file");
230                         break;
231                 }
232                 len -= ret;
233                 buf += ret;
234         }
235
236         close(fd);
237         log_err("       %s data dumped as %s\n", type, fname);
238         free(ptr);
239 }
240
241 /*
242  * Dump the contents of the read block and re-generate the correct data
243  * and dump that too.
244  */
245 static void dump_verify_buffers(struct verify_header *hdr, struct vcont *vc)
246 {
247         struct thread_data *td = vc->td;
248         struct io_u *io_u = vc->io_u;
249         unsigned long hdr_offset;
250         struct io_u dummy;
251         void *buf;
252
253         /*
254          * Dump the contents we just read off disk
255          */
256         hdr_offset = vc->hdr_num * hdr->len;
257
258         dump_buf(io_u->buf + hdr_offset, hdr->len, io_u->offset + hdr_offset,
259                         "received", vc->io_u->file);
260
261         /*
262          * Allocate a new buf and re-generate the original data
263          */
264         buf = malloc(io_u->buflen);
265         dummy = *io_u;
266         dummy.buf = buf;
267         dummy.rand_seed = hdr->rand_seed;
268         dummy.buf_filled_len = 0;
269
270         fill_pattern_headers(td, &dummy, hdr->rand_seed, 1);
271
272         dump_buf(buf + hdr_offset, hdr->len, io_u->offset + hdr_offset,
273                         "expected", vc->io_u->file);
274         free(buf);
275 }
276
277 static void log_verify_failure(struct verify_header *hdr, struct vcont *vc)
278 {
279         unsigned long long offset;
280
281         offset = vc->io_u->offset;
282         offset += vc->hdr_num * hdr->len;
283         log_err("%.8s: verify failed at file %s offset %llu, length %u\n",
284                         vc->name, vc->io_u->file->file_name, offset, hdr->len);
285
286         if (vc->good_crc && vc->bad_crc) {
287                 log_err("       Expected CRC: ");
288                 hexdump(vc->good_crc, vc->crc_len);
289                 log_err("       Received CRC: ");
290                 hexdump(vc->bad_crc, vc->crc_len);
291         }
292
293         dump_verify_buffers(hdr, vc);
294 }
295
296 /*
297  * Return data area 'header_num'
298  */
299 static inline void *io_u_verify_off(struct verify_header *hdr, struct vcont *vc)
300 {
301         return vc->io_u->buf + vc->hdr_num * hdr->len + hdr_size(hdr);
302 }
303
304 static int verify_io_u_meta(struct verify_header *hdr, struct thread_data *td,
305                             struct vcont *vc)
306 {
307         struct vhdr_meta *vh = hdr_priv(hdr);
308         struct io_u *io_u = vc->io_u;
309
310         dprint(FD_VERIFY, "meta verify io_u %p, len %u\n", io_u, hdr->len);
311
312         if (vh->offset == io_u->offset + vc->hdr_num * td->o.verify_interval)
313                 return 0;
314
315         vc->name = "meta";
316         log_verify_failure(hdr, vc);
317         return EILSEQ;
318 }
319
320 static int verify_io_u_sha512(struct verify_header *hdr, struct vcont *vc)
321 {
322         void *p = io_u_verify_off(hdr, vc);
323         struct vhdr_sha512 *vh = hdr_priv(hdr);
324         uint8_t sha512[128];
325         struct sha512_ctx sha512_ctx = {
326                 .buf = sha512,
327         };
328
329         dprint(FD_VERIFY, "sha512 verify io_u %p, len %u\n", vc->io_u, hdr->len);
330
331         sha512_init(&sha512_ctx);
332         sha512_update(&sha512_ctx, p, hdr->len - hdr_size(hdr));
333
334         if (!memcmp(vh->sha512, sha512_ctx.buf, sizeof(sha512)))
335                 return 0;
336
337         vc->name = "sha512";
338         vc->good_crc = vh->sha512;
339         vc->bad_crc = sha512_ctx.buf;
340         vc->crc_len = sizeof(vh->sha512);
341         log_verify_failure(hdr, vc);
342         return EILSEQ;
343 }
344
345 static int verify_io_u_sha256(struct verify_header *hdr, struct vcont *vc)
346 {
347         void *p = io_u_verify_off(hdr, vc);
348         struct vhdr_sha256 *vh = hdr_priv(hdr);
349         uint8_t sha256[64];
350         struct sha256_ctx sha256_ctx = {
351                 .buf = sha256,
352         };
353
354         dprint(FD_VERIFY, "sha256 verify io_u %p, len %u\n", vc->io_u, hdr->len);
355
356         sha256_init(&sha256_ctx);
357         sha256_update(&sha256_ctx, p, hdr->len - hdr_size(hdr));
358
359         if (!memcmp(vh->sha256, sha256_ctx.buf, sizeof(sha256)))
360                 return 0;
361
362         vc->name = "sha256";
363         vc->good_crc = vh->sha256;
364         vc->bad_crc = sha256_ctx.buf;
365         vc->crc_len = sizeof(vh->sha256);
366         log_verify_failure(hdr, vc);
367         return EILSEQ;
368 }
369
370 static int verify_io_u_sha1(struct verify_header *hdr, struct vcont *vc)
371 {
372         void *p = io_u_verify_off(hdr, vc);
373         struct vhdr_sha1 *vh = hdr_priv(hdr);
374         uint32_t sha1[5];
375         struct sha1_ctx sha1_ctx = {
376                 .H = sha1,
377         };
378
379         dprint(FD_VERIFY, "sha1 verify io_u %p, len %u\n", vc->io_u, hdr->len);
380
381         sha1_init(&sha1_ctx);
382         sha1_update(&sha1_ctx, p, hdr->len - hdr_size(hdr));
383
384         if (!memcmp(vh->sha1, sha1_ctx.H, sizeof(sha1)))
385                 return 0;
386
387         vc->name = "sha1";
388         vc->good_crc = vh->sha1;
389         vc->bad_crc = sha1_ctx.H;
390         vc->crc_len = sizeof(vh->sha1);
391         log_verify_failure(hdr, vc);
392         return EILSEQ;
393 }
394
395 static int verify_io_u_crc7(struct verify_header *hdr, struct vcont *vc)
396 {
397         void *p = io_u_verify_off(hdr, vc);
398         struct vhdr_crc7 *vh = hdr_priv(hdr);
399         unsigned char c;
400
401         dprint(FD_VERIFY, "crc7 verify io_u %p, len %u\n", vc->io_u, hdr->len);
402
403         c = crc7(p, hdr->len - hdr_size(hdr));
404
405         if (c == vh->crc7)
406                 return 0;
407
408         vc->name = "crc7";
409         vc->good_crc = &vh->crc7;
410         vc->bad_crc = &c;
411         vc->crc_len = 1;
412         log_verify_failure(hdr, vc);
413         return EILSEQ;
414 }
415
416 static int verify_io_u_crc16(struct verify_header *hdr, struct vcont *vc)
417 {
418         void *p = io_u_verify_off(hdr, vc);
419         struct vhdr_crc16 *vh = hdr_priv(hdr);
420         unsigned short c;
421
422         dprint(FD_VERIFY, "crc16 verify io_u %p, len %u\n", vc->io_u, hdr->len);
423
424         c = crc16(p, hdr->len - hdr_size(hdr));
425
426         if (c == vh->crc16)
427                 return 0;
428
429         vc->name = "crc16";
430         vc->good_crc = &vh->crc16;
431         vc->bad_crc = &c;
432         vc->crc_len = 2;
433         log_verify_failure(hdr, vc);
434         return EILSEQ;
435 }
436
437 static int verify_io_u_crc64(struct verify_header *hdr, struct vcont *vc)
438 {
439         void *p = io_u_verify_off(hdr, vc);
440         struct vhdr_crc64 *vh = hdr_priv(hdr);
441         unsigned long long c;
442
443         dprint(FD_VERIFY, "crc64 verify io_u %p, len %u\n", vc->io_u, hdr->len);
444
445         c = crc64(p, hdr->len - hdr_size(hdr));
446
447         if (c == vh->crc64)
448                 return 0;
449
450         vc->name = "crc64";
451         vc->good_crc = &vh->crc64;
452         vc->bad_crc = &c;
453         vc->crc_len = 8;
454         log_verify_failure(hdr, vc);
455         return EILSEQ;
456 }
457
458 static int verify_io_u_crc32(struct verify_header *hdr, struct vcont *vc)
459 {
460         void *p = io_u_verify_off(hdr, vc);
461         struct vhdr_crc32 *vh = hdr_priv(hdr);
462         uint32_t c;
463
464         dprint(FD_VERIFY, "crc32 verify io_u %p, len %u\n", vc->io_u, hdr->len);
465
466         c = crc32(p, hdr->len - hdr_size(hdr));
467
468         if (c == vh->crc32)
469                 return 0;
470
471         vc->name = "crc32";
472         vc->good_crc = &vh->crc32;
473         vc->bad_crc = &c;
474         vc->crc_len = 4;
475         log_verify_failure(hdr, vc);
476         return EILSEQ;
477 }
478
479 static int verify_io_u_crc32c(struct verify_header *hdr, struct vcont *vc)
480 {
481         void *p = io_u_verify_off(hdr, vc);
482         struct vhdr_crc32 *vh = hdr_priv(hdr);
483         uint32_t c;
484
485         dprint(FD_VERIFY, "crc32c verify io_u %p, len %u\n", vc->io_u, hdr->len);
486
487         if (hdr->verify_type == VERIFY_CRC32C_INTEL)
488                 c = crc32c_intel(p, hdr->len - hdr_size(hdr));
489         else
490                 c = crc32c(p, hdr->len - hdr_size(hdr));
491
492         if (c == vh->crc32)
493                 return 0;
494
495         vc->name = "crc32c";
496         vc->good_crc = &vh->crc32;
497         vc->bad_crc = &c;
498         vc->crc_len = 4;
499         log_verify_failure(hdr, vc);
500         return EILSEQ;
501 }
502
503 static int verify_io_u_md5(struct verify_header *hdr, struct vcont *vc)
504 {
505         void *p = io_u_verify_off(hdr, vc);
506         struct vhdr_md5 *vh = hdr_priv(hdr);
507         uint32_t hash[MD5_HASH_WORDS];
508         struct md5_ctx md5_ctx = {
509                 .hash = hash,
510         };
511
512         dprint(FD_VERIFY, "md5 verify io_u %p, len %u\n", vc->io_u, hdr->len);
513
514         md5_init(&md5_ctx);
515         md5_update(&md5_ctx, p, hdr->len - hdr_size(hdr));
516
517         if (!memcmp(vh->md5_digest, md5_ctx.hash, sizeof(hash)))
518                 return 0;
519
520         vc->name = "md5";
521         vc->good_crc = vh->md5_digest;
522         vc->bad_crc = md5_ctx.hash;
523         vc->crc_len = sizeof(hash);
524         log_verify_failure(hdr, vc);
525         return EILSEQ;
526 }
527
528 static unsigned int hweight8(unsigned int w)
529 {
530         unsigned int res = w - ((w >> 1) & 0x55);
531
532         res = (res & 0x33) + ((res >> 2) & 0x33);
533         return (res + (res >> 4)) & 0x0F;
534 }
535
536 int verify_io_u_pattern(struct verify_header *hdr, struct vcont *vc)
537 {
538         struct thread_data *td = vc->td;
539         struct io_u *io_u = vc->io_u;
540         char *pattern = td->o.verify_pattern;
541         unsigned long pattern_size = td->o.verify_pattern_bytes;
542         unsigned int hdr_size = __hdr_size(td->o.verify);
543         char *buf = (void *) hdr + hdr_size;
544         unsigned int hdr_inc = get_hdr_inc(td, io_u);
545         unsigned int len = hdr_inc - hdr_size;
546         unsigned int mod = hdr_size % pattern_size;
547         unsigned int i;
548
549         for (i = 0; i < len; i++) {
550                 if (buf[i] != pattern[mod]) {
551                         unsigned int bits;
552
553                         bits = hweight8(buf[i] ^ pattern[mod]);
554                         log_err("fio: got pattern %x, wanted %x. Bad bits %d\n",
555                                 buf[i], pattern[mod], bits);
556                         log_err("fio: bad pattern block offset %u\n", i);
557                         dump_verify_buffers(hdr, vc);
558                         return EILSEQ;
559                 }
560                 mod++;
561                 if (mod == pattern_size)
562                         mod = 0;
563         }
564
565         return 0;
566 }
567
568 /*
569  * Push IO verification to a separate thread
570  */
571 int verify_io_u_async(struct thread_data *td, struct io_u *io_u)
572 {
573         if (io_u->file)
574                 put_file_log(td, io_u->file);
575
576         io_u->file = NULL;
577
578         pthread_mutex_lock(&td->io_u_lock);
579         
580         if (io_u->flags & IO_U_F_IN_CUR_DEPTH) {
581                 td->cur_depth--;
582                 io_u->flags &= ~IO_U_F_IN_CUR_DEPTH;
583         }
584         flist_del(&io_u->list);
585         flist_add_tail(&io_u->list, &td->verify_list);
586         io_u->flags |= IO_U_F_FREE_DEF;
587         pthread_mutex_unlock(&td->io_u_lock);
588
589         pthread_cond_signal(&td->verify_cond);
590         return 0;
591 }
592
593 static int verify_trimmed_io_u(struct thread_data *td, struct io_u *io_u)
594 {
595         static char zero_buf[1024];
596         unsigned int this_len, len;
597         int ret = 0;
598         void *p;
599
600         if (!td->o.trim_zero)
601                 return 0;
602
603         len = io_u->buflen;
604         p = io_u->buf;
605         do {
606                 this_len = sizeof(zero_buf);
607                 if (this_len > len)
608                         this_len = len;
609                 if (memcmp(p, zero_buf, this_len)) {
610                         ret = EILSEQ;
611                         break;
612                 }
613                 len -= this_len;
614                 p += this_len;
615         } while (len);
616
617         if (!ret)
618                 return 0;
619
620         log_err("trim: verify failed at file %s offset %llu, length %lu"
621                 ", block offset %lu\n",
622                         io_u->file->file_name, io_u->offset, io_u->buflen,
623                         (unsigned long) (p - io_u->buf));
624         return ret;
625 }
626
627 int verify_io_u(struct thread_data *td, struct io_u *io_u)
628 {
629         struct verify_header *hdr;
630         unsigned int hdr_size, hdr_inc, hdr_num = 0;
631         void *p;
632         int ret;
633
634         if (td->o.verify == VERIFY_NULL || io_u->ddir != DDIR_READ)
635                 return 0;
636         if (io_u->flags & IO_U_F_TRIMMED) {
637                 ret = verify_trimmed_io_u(td, io_u);
638                 goto done;
639         }
640
641         hdr_inc = get_hdr_inc(td, io_u);
642
643         ret = 0;
644         for (p = io_u->buf; p < io_u->buf + io_u->buflen;
645              p += hdr_inc, hdr_num++) {
646                 struct vcont vc = {
647                         .io_u           = io_u,
648                         .hdr_num        = hdr_num,
649                         .td             = td,
650                 };
651
652                 if (ret && td->o.verify_fatal)
653                         break;
654
655                 hdr_size = __hdr_size(td->o.verify);
656                 if (td->o.verify_offset)
657                         memswp(p, p + td->o.verify_offset, hdr_size);
658                 hdr = p;
659
660                 if (hdr->fio_magic != FIO_HDR_MAGIC) {
661                         log_err("verify: bad magic header %x, wanted %x at file %s offset %llu, length %u\n",
662                                 hdr->fio_magic, FIO_HDR_MAGIC,
663                                 io_u->file->file_name,
664                                 io_u->offset + hdr_num * hdr->len, hdr->len);
665                         return EILSEQ;
666                 }
667
668                 if (td->o.verify_pattern_bytes) {
669                         dprint(FD_VERIFY, "pattern verify io_u %p, len %u\n",
670                                                                 io_u, hdr->len);
671                         ret = verify_io_u_pattern(hdr, &vc);
672                         if (ret) {
673                                 log_err("pattern: verify failed at file %s offset %llu, length %u\n",
674                                         io_u->file->file_name,
675                                         io_u->offset + hdr_num * hdr->len,
676                                         hdr->len);
677                         }
678
679                         /*
680                          * Also verify the meta data, if applicable
681                          */
682                         if (hdr->verify_type == VERIFY_META)
683                                 ret |= verify_io_u_meta(hdr, td, &vc);
684                         continue;
685                 }
686
687                 switch (hdr->verify_type) {
688                 case VERIFY_MD5:
689                         ret = verify_io_u_md5(hdr, &vc);
690                         break;
691                 case VERIFY_CRC64:
692                         ret = verify_io_u_crc64(hdr, &vc);
693                         break;
694                 case VERIFY_CRC32C:
695                 case VERIFY_CRC32C_INTEL:
696                         ret = verify_io_u_crc32c(hdr, &vc);
697                         break;
698                 case VERIFY_CRC32:
699                         ret = verify_io_u_crc32(hdr, &vc);
700                         break;
701                 case VERIFY_CRC16:
702                         ret = verify_io_u_crc16(hdr, &vc);
703                         break;
704                 case VERIFY_CRC7:
705                         ret = verify_io_u_crc7(hdr, &vc);
706                         break;
707                 case VERIFY_SHA256:
708                         ret = verify_io_u_sha256(hdr, &vc);
709                         break;
710                 case VERIFY_SHA512:
711                         ret = verify_io_u_sha512(hdr, &vc);
712                         break;
713                 case VERIFY_META:
714                         ret = verify_io_u_meta(hdr, td, &vc);
715                         break;
716                 case VERIFY_SHA1:
717                         ret = verify_io_u_sha1(hdr, &vc);
718                         break;
719                 default:
720                         log_err("Bad verify type %u\n", hdr->verify_type);
721                         ret = EINVAL;
722                 }
723         }
724
725 done:
726         if (ret && td->o.verify_fatal)
727                 td->terminate = 1;
728
729         return ret;
730 }
731
732 static void fill_meta(struct verify_header *hdr, struct thread_data *td,
733                       struct io_u *io_u, unsigned int header_num)
734 {
735         struct vhdr_meta *vh = hdr_priv(hdr);
736
737         vh->thread = td->thread_number;
738
739         vh->time_sec = io_u->start_time.tv_sec;
740         vh->time_usec = io_u->start_time.tv_usec;
741
742         vh->numberio = td->io_issues[DDIR_WRITE];
743
744         vh->offset = io_u->offset + header_num * td->o.verify_interval;
745 }
746
747 static void fill_sha512(struct verify_header *hdr, void *p, unsigned int len)
748 {
749         struct vhdr_sha512 *vh = hdr_priv(hdr);
750         struct sha512_ctx sha512_ctx = {
751                 .buf = vh->sha512,
752         };
753
754         sha512_init(&sha512_ctx);
755         sha512_update(&sha512_ctx, p, len);
756 }
757
758 static void fill_sha256(struct verify_header *hdr, void *p, unsigned int len)
759 {
760         struct vhdr_sha256 *vh = hdr_priv(hdr);
761         struct sha256_ctx sha256_ctx = {
762                 .buf = vh->sha256,
763         };
764
765         sha256_init(&sha256_ctx);
766         sha256_update(&sha256_ctx, p, len);
767 }
768
769 static void fill_sha1(struct verify_header *hdr, void *p, unsigned int len)
770 {
771         struct vhdr_sha1 *vh = hdr_priv(hdr);
772         struct sha1_ctx sha1_ctx = {
773                 .H = vh->sha1,
774         };
775
776         sha1_init(&sha1_ctx);
777         sha1_update(&sha1_ctx, p, len);
778 }
779
780 static void fill_crc7(struct verify_header *hdr, void *p, unsigned int len)
781 {
782         struct vhdr_crc7 *vh = hdr_priv(hdr);
783
784         vh->crc7 = crc7(p, len);
785 }
786
787 static void fill_crc16(struct verify_header *hdr, void *p, unsigned int len)
788 {
789         struct vhdr_crc16 *vh = hdr_priv(hdr);
790
791         vh->crc16 = crc16(p, len);
792 }
793
794 static void fill_crc32(struct verify_header *hdr, void *p, unsigned int len)
795 {
796         struct vhdr_crc32 *vh = hdr_priv(hdr);
797
798         vh->crc32 = crc32(p, len);
799 }
800
801 static void fill_crc32c(struct verify_header *hdr, void *p, unsigned int len)
802 {
803         struct vhdr_crc32 *vh = hdr_priv(hdr);
804
805         if (hdr->verify_type == VERIFY_CRC32C_INTEL)
806                 vh->crc32 = crc32c_intel(p, len);
807         else
808                 vh->crc32 = crc32c(p, len);
809 }
810
811 static void fill_crc64(struct verify_header *hdr, void *p, unsigned int len)
812 {
813         struct vhdr_crc64 *vh = hdr_priv(hdr);
814
815         vh->crc64 = crc64(p, len);
816 }
817
818 static void fill_md5(struct verify_header *hdr, void *p, unsigned int len)
819 {
820         struct vhdr_md5 *vh = hdr_priv(hdr);
821         struct md5_ctx md5_ctx = {
822                 .hash = (uint32_t *) vh->md5_digest,
823         };
824
825         md5_init(&md5_ctx);
826         md5_update(&md5_ctx, p, len);
827 }
828
829 static void populate_hdr(struct thread_data *td, struct io_u *io_u,
830                          struct verify_header *hdr, unsigned int header_num,
831                          unsigned int header_len)
832 {
833         unsigned int data_len;
834         void *data, *p;
835
836         p = (void *) hdr;
837
838         hdr->fio_magic = FIO_HDR_MAGIC;
839         hdr->len = header_len;
840         hdr->verify_type = td->o.verify;
841         hdr->rand_seed = io_u->rand_seed;
842         data_len = header_len - hdr_size(hdr);
843
844         data = p + hdr_size(hdr);
845         switch (td->o.verify) {
846         case VERIFY_MD5:
847                 dprint(FD_VERIFY, "fill md5 io_u %p, len %u\n",
848                                                 io_u, hdr->len);
849                 fill_md5(hdr, data, data_len);
850                 break;
851         case VERIFY_CRC64:
852                 dprint(FD_VERIFY, "fill crc64 io_u %p, len %u\n",
853                                                 io_u, hdr->len);
854                 fill_crc64(hdr, data, data_len);
855                 break;
856         case VERIFY_CRC32C:
857         case VERIFY_CRC32C_INTEL:
858                 dprint(FD_VERIFY, "fill crc32c io_u %p, len %u\n",
859                                                 io_u, hdr->len);
860                 fill_crc32c(hdr, data, data_len);
861                 break;
862         case VERIFY_CRC32:
863                 dprint(FD_VERIFY, "fill crc32 io_u %p, len %u\n",
864                                                 io_u, hdr->len);
865                 fill_crc32(hdr, data, data_len);
866                 break;
867         case VERIFY_CRC16:
868                 dprint(FD_VERIFY, "fill crc16 io_u %p, len %u\n",
869                                                 io_u, hdr->len);
870                 fill_crc16(hdr, data, data_len);
871                 break;
872         case VERIFY_CRC7:
873                 dprint(FD_VERIFY, "fill crc7 io_u %p, len %u\n",
874                                                 io_u, hdr->len);
875                 fill_crc7(hdr, data, data_len);
876                 break;
877         case VERIFY_SHA256:
878                 dprint(FD_VERIFY, "fill sha256 io_u %p, len %u\n",
879                                                 io_u, hdr->len);
880                 fill_sha256(hdr, data, data_len);
881                 break;
882         case VERIFY_SHA512:
883                 dprint(FD_VERIFY, "fill sha512 io_u %p, len %u\n",
884                                                 io_u, hdr->len);
885                 fill_sha512(hdr, data, data_len);
886                 break;
887         case VERIFY_META:
888                 dprint(FD_VERIFY, "fill meta io_u %p, len %u\n",
889                                                 io_u, hdr->len);
890                 fill_meta(hdr, td, io_u, header_num);
891                 break;
892         case VERIFY_SHA1:
893                 dprint(FD_VERIFY, "fill sha1 io_u %p, len %u\n",
894                                                 io_u, hdr->len);
895                 fill_sha1(hdr, data, data_len);
896                 break;
897         default:
898                 log_err("fio: bad verify type: %d\n", td->o.verify);
899                 assert(0);
900         }
901         if (td->o.verify_offset)
902                 memswp(p, p + td->o.verify_offset, hdr_size(hdr));
903 }
904
905 /*
906  * fill body of io_u->buf with random data and add a header with the
907  * checksum of choice
908  */
909 void populate_verify_io_u(struct thread_data *td, struct io_u *io_u)
910 {
911         if (td->o.verify == VERIFY_NULL)
912                 return;
913
914         fill_pattern_headers(td, io_u, 0, 0);
915 }
916
917 int get_next_verify(struct thread_data *td, struct io_u *io_u)
918 {
919         struct io_piece *ipo = NULL;
920
921         /*
922          * this io_u is from a requeue, we already filled the offsets
923          */
924         if (io_u->file)
925                 return 0;
926
927         if (!RB_EMPTY_ROOT(&td->io_hist_tree)) {
928                 struct rb_node *n = rb_first(&td->io_hist_tree);
929
930                 ipo = rb_entry(n, struct io_piece, rb_node);
931                 rb_erase(n, &td->io_hist_tree);
932                 assert(ipo->flags & IP_F_ONRB);
933                 ipo->flags &= ~IP_F_ONRB;
934         } else if (!flist_empty(&td->io_hist_list)) {
935                 ipo = flist_entry(td->io_hist_list.next, struct io_piece, list);
936                 flist_del(&ipo->list);
937                 assert(ipo->flags & IP_F_ONLIST);
938                 ipo->flags &= ~IP_F_ONLIST;
939         }
940
941         if (ipo) {
942                 td->io_hist_len--;
943
944                 io_u->offset = ipo->offset;
945                 io_u->buflen = ipo->len;
946                 io_u->file = ipo->file;
947
948                 if (ipo->flags & IP_F_TRIMMED)
949                         io_u->flags |= IO_U_F_TRIMMED;
950
951                 if (!fio_file_open(io_u->file)) {
952                         int r = td_io_open_file(td, io_u->file);
953
954                         if (r) {
955                                 dprint(FD_VERIFY, "failed file %s open\n",
956                                                 io_u->file->file_name);
957                                 return 1;
958                         }
959                 }
960
961                 get_file(ipo->file);
962                 assert(fio_file_open(io_u->file));
963                 io_u->ddir = DDIR_READ;
964                 io_u->xfer_buf = io_u->buf;
965                 io_u->xfer_buflen = io_u->buflen;
966
967                 remove_trim_entry(td, ipo);
968                 free(ipo);
969                 dprint(FD_VERIFY, "get_next_verify: ret io_u %p\n", io_u);
970                 return 0;
971         }
972
973         dprint(FD_VERIFY, "get_next_verify: empty\n");
974         return 1;
975 }
976
977 static void *verify_async_thread(void *data)
978 {
979         struct thread_data *td = data;
980         struct io_u *io_u;
981         int ret = 0;
982
983         if (td->o.verify_cpumask_set &&
984             fio_setaffinity(td->pid, td->o.verify_cpumask)) {
985                 log_err("fio: failed setting verify thread affinity\n");
986                 goto done;
987         }
988
989         do {
990                 FLIST_HEAD(list);
991
992                 read_barrier();
993                 if (td->verify_thread_exit)
994                         break;
995
996                 pthread_mutex_lock(&td->io_u_lock);
997
998                 while (flist_empty(&td->verify_list) &&
999                        !td->verify_thread_exit) {
1000                         ret = pthread_cond_wait(&td->verify_cond,
1001                                                         &td->io_u_lock);
1002                         if (ret) {
1003                                 pthread_mutex_unlock(&td->io_u_lock);
1004                                 break;
1005                         }
1006                 }
1007
1008                 flist_splice_init(&td->verify_list, &list);
1009                 pthread_mutex_unlock(&td->io_u_lock);
1010
1011                 if (flist_empty(&list))
1012                         continue;
1013
1014                 while (!flist_empty(&list)) {
1015                         io_u = flist_entry(list.next, struct io_u, list);
1016                         flist_del_init(&io_u->list);
1017
1018                         ret = verify_io_u(td, io_u);
1019                         put_io_u(td, io_u);
1020                         if (!ret)
1021                                 continue;
1022                         if (td->o.continue_on_error &&
1023                             td_non_fatal_error(ret)) {
1024                                 update_error_count(td, ret);
1025                                 td_clear_error(td);
1026                                 ret = 0;
1027                         }
1028                 }
1029         } while (!ret);
1030
1031         if (ret) {
1032                 td_verror(td, ret, "async_verify");
1033                 if (td->o.verify_fatal)
1034                         td->terminate = 1;
1035         }
1036
1037 done:
1038         pthread_mutex_lock(&td->io_u_lock);
1039         td->nr_verify_threads--;
1040         pthread_mutex_unlock(&td->io_u_lock);
1041
1042         pthread_cond_signal(&td->free_cond);
1043         return NULL;
1044 }
1045
1046 int verify_async_init(struct thread_data *td)
1047 {
1048         int i, ret;
1049         pthread_attr_t attr;
1050
1051         pthread_attr_init(&attr);
1052         pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN);
1053
1054         td->verify_thread_exit = 0;
1055
1056         td->verify_threads = malloc(sizeof(pthread_t) * td->o.verify_async);
1057         for (i = 0; i < td->o.verify_async; i++) {
1058                 ret = pthread_create(&td->verify_threads[i], &attr,
1059                                         verify_async_thread, td);
1060                 if (ret) {
1061                         log_err("fio: async verify creation failed: %s\n",
1062                                         strerror(ret));
1063                         break;
1064                 }
1065                 ret = pthread_detach(td->verify_threads[i]);
1066                 if (ret) {
1067                         log_err("fio: async verify thread detach failed: %s\n",
1068                                         strerror(ret));
1069                         break;
1070                 }
1071                 td->nr_verify_threads++;
1072         }
1073
1074         pthread_attr_destroy(&attr);
1075
1076         if (i != td->o.verify_async) {
1077                 log_err("fio: only %d verify threads started, exiting\n", i);
1078                 td->verify_thread_exit = 1;
1079                 write_barrier();
1080                 pthread_cond_broadcast(&td->verify_cond);
1081                 return 1;
1082         }
1083
1084         return 0;
1085 }
1086
1087 void verify_async_exit(struct thread_data *td)
1088 {
1089         td->verify_thread_exit = 1;
1090         write_barrier();
1091         pthread_cond_broadcast(&td->verify_cond);
1092
1093         pthread_mutex_lock(&td->io_u_lock);
1094
1095         while (td->nr_verify_threads)
1096                 pthread_cond_wait(&td->free_cond, &td->io_u_lock);
1097
1098         pthread_mutex_unlock(&td->io_u_lock);
1099         free(td->verify_threads);
1100         td->verify_threads = NULL;
1101 }