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