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