2 * IO verification helpers
11 static void fill_random_bytes(struct thread_data *td,
12 unsigned char *p, unsigned int len)
18 r = os_random_long(&td->verify_state);
21 * lrand48_r seems to be broken and only fill the bottom
22 * 32-bits, even on 64-bit archs with 64-bit longs
35 void memswp(void* buf1, void* buf2, unsigned int len)
37 struct verify_header swap;
38 memcpy(&swap, buf1, len);
39 memcpy(buf1, buf2, len);
40 memcpy(buf2, &swap, len);
43 static void hexdump(void *buffer, int len)
45 unsigned char *p = buffer;
48 for (i = 0; i < len; i++)
49 log_info("%02x", p[i]);
53 static int verify_io_u_crc7(struct verify_header *hdr, struct io_u *io_u,
54 unsigned char header_num)
56 unsigned char *p = io_u->buf;
59 p += header_num * hdr->len + sizeof(*hdr);
60 c = crc7(p, hdr->len - sizeof(*hdr));
63 log_err("crc7: verify failed at %llu/%u\n",
64 io_u->offset + header_num * hdr->len,
66 log_err("crc7: wanted %x, got %x\n", hdr->crc7, c);
73 static int verify_io_u_crc16(struct verify_header *hdr, struct io_u *io_u,
74 unsigned int header_num)
76 unsigned char *p = io_u->buf;
79 p += header_num * hdr->len + sizeof(*hdr);
80 c = crc16(p, hdr->len - sizeof(*hdr));
82 if (c != hdr->crc16) {
83 log_err("crc16: verify failed at %llu/%u\n",
84 io_u->offset + header_num * hdr->len,
86 log_err("crc16: wanted %x, got %x\n", hdr->crc16, c);
93 static int verify_io_u_crc64(struct verify_header *hdr, struct io_u *io_u,
94 unsigned int header_num)
96 unsigned char *p = io_u->buf;
99 p += header_num * hdr->len + sizeof(*hdr);
100 c = crc64(p, hdr->len - sizeof(*hdr));
102 if (c != hdr->crc64) {
103 log_err("crc64: verify failed at %llu/%u\n",
104 io_u->offset + header_num * hdr->len,
106 log_err("crc64: wanted %llx, got %llx\n", hdr->crc64, c);
113 static int verify_io_u_crc32(struct verify_header *hdr, struct io_u *io_u,
114 unsigned int header_num)
116 unsigned char *p = io_u->buf;
119 p += header_num * hdr->len + sizeof(*hdr);
120 c = crc32(p, hdr->len - sizeof(*hdr));
122 if (c != hdr->crc32) {
123 log_err("crc32: verify failed at %llu/%u\n",
124 io_u->offset + header_num * hdr->len,
126 log_err("crc32: wanted %lx, got %lx\n", hdr->crc32, c);
133 static int verify_io_u_md5(struct verify_header *hdr, struct io_u *io_u,
134 unsigned int header_num)
136 unsigned char *p = io_u->buf;
137 uint32_t hash[MD5_HASH_WORDS];
138 struct md5_ctx md5_ctx = {
142 p += header_num * hdr->len + sizeof(*hdr);
143 md5_update(&md5_ctx, p, hdr->len - sizeof(*hdr));
145 if (memcmp(hdr->md5_digest, md5_ctx.hash, sizeof(md5_ctx.hash))) {
146 log_err("md5: verify failed at %llu/%u\n",
147 io_u->offset + header_num * hdr->len,
149 hexdump(hdr->md5_digest, sizeof(hdr->md5_digest));
150 hexdump(md5_ctx.hash, sizeof(hash));
157 int verify_io_u(struct thread_data *td, struct io_u *io_u)
159 unsigned char *p = (unsigned char*) io_u->buf;
160 struct verify_header *hdr;
161 unsigned int hdr_inc, hdr_num = 0;
164 if (td->o.verify == VERIFY_NULL || io_u->ddir != DDIR_READ)
167 hdr_inc = io_u->buflen;
168 if (td->o.header_interval)
169 hdr_inc = td->o.header_interval;
171 for (; p < (unsigned char*) io_u->buf + io_u->buflen; p += hdr_inc) {
172 if (td->o.header_offset)
173 memswp(p, &p[td->o.header_offset], sizeof(*hdr));
175 hdr = (struct verify_header*) p;
177 if (hdr->fio_magic != FIO_HDR_MAGIC) {
178 log_err("Bad verify header %x\n", hdr->fio_magic);
182 switch (hdr->verify_type) {
184 ret = verify_io_u_md5(hdr, io_u, hdr_num);
187 ret = verify_io_u_crc64(hdr, io_u, hdr_num);
190 ret = verify_io_u_crc32(hdr, io_u, hdr_num);
193 ret = verify_io_u_crc16(hdr, io_u, hdr_num);
196 ret = verify_io_u_crc7(hdr, io_u, hdr_num);
199 log_err("Bad verify type %u\n", hdr->verify_type);
208 static void fill_crc7(struct verify_header *hdr, void *p, unsigned int len)
210 hdr->crc7 = crc7(p, len);
213 static void fill_crc16(struct verify_header *hdr, void *p, unsigned int len)
215 hdr->crc16 = crc16(p, len);
218 static void fill_crc32(struct verify_header *hdr, void *p, unsigned int len)
220 hdr->crc32 = crc32(p, len);
223 static void fill_crc64(struct verify_header *hdr, void *p, unsigned int len)
225 hdr->crc64 = crc64(p, len);
228 static void fill_md5(struct verify_header *hdr, void *p, unsigned int len)
230 struct md5_ctx md5_ctx = {
231 .hash = (uint32_t *) hdr->md5_digest,
234 md5_update(&md5_ctx, p, len);
238 * fill body of io_u->buf with random data and add a header with the
239 * crc32 or md5 sum of that data.
241 void populate_verify_io_u(struct thread_data *td, struct io_u *io_u)
243 struct verify_header *hdr;
244 unsigned char *p = io_u->buf, *data;
245 unsigned int hdr_inc, data_len;
247 if (td->o.verify == VERIFY_NULL)
250 fill_random_bytes(td, p, io_u->buflen);
252 hdr_inc = io_u->buflen;
253 if (td->o.header_interval)
254 hdr_inc = td->o.header_interval;
255 data_len = hdr_inc - sizeof(*hdr);
257 for (;p < (unsigned char*) io_u->buf + io_u->buflen; p += hdr_inc) {
258 hdr = (struct verify_header*) p;
260 hdr->fio_magic = FIO_HDR_MAGIC;
261 hdr->verify_type = td->o.verify;
264 data = p + sizeof(*hdr);
265 switch (td->o.verify) {
267 fill_md5(hdr, data, data_len);
270 fill_crc64(hdr, data, data_len);
273 fill_crc32(hdr, data, data_len);
276 fill_crc16(hdr, data, data_len);
279 fill_crc7(hdr, data, data_len);
282 log_err("fio: bad verify type: %d\n", td->o.verify);
285 if (td->o.header_offset)
286 memswp(p, &p[td->o.header_offset], sizeof(*hdr));
290 int get_next_verify(struct thread_data *td, struct io_u *io_u)
292 struct io_piece *ipo = NULL;
295 * this io_u is from a requeue, we already filled the offsets
300 if (!RB_EMPTY_ROOT(&td->io_hist_tree)) {
301 struct rb_node *n = rb_first(&td->io_hist_tree);
303 ipo = rb_entry(n, struct io_piece, rb_node);
304 rb_erase(n, &td->io_hist_tree);
305 } else if (!list_empty(&td->io_hist_list)) {
306 ipo = list_entry(td->io_hist_list.next, struct io_piece, list);
307 list_del(&ipo->list);
311 io_u->offset = ipo->offset;
312 io_u->buflen = ipo->len;
313 io_u->file = ipo->file;
315 if ((io_u->file->flags & FIO_FILE_OPEN) == 0) {
316 int r = td_io_open_file(td, io_u->file);
323 assert(io_u->file->flags & FIO_FILE_OPEN);
324 io_u->ddir = DDIR_READ;
325 io_u->xfer_buf = io_u->buf;
326 io_u->xfer_buflen = io_u->buflen;