Merge branch 'taras/nfs-upstream' of https://github.com/tarasglek/fio-1
[fio.git] / zbd.c
1 /*
2  * Copyright (C) 2018 Western Digital Corporation or its affiliates.
3  *
4  * This file is released under the GPL.
5  */
6
7 #include <errno.h>
8 #include <string.h>
9 #include <stdlib.h>
10 #include <fcntl.h>
11 #include <sys/stat.h>
12 #include <unistd.h>
13
14 #include "os/os.h"
15 #include "file.h"
16 #include "fio.h"
17 #include "lib/pow2.h"
18 #include "log.h"
19 #include "oslib/asprintf.h"
20 #include "smalloc.h"
21 #include "verify.h"
22 #include "pshared.h"
23 #include "zbd.h"
24
25 /**
26  * zbd_get_zoned_model - Get a device zoned model
27  * @td: FIO thread data
28  * @f: FIO file for which to get model information
29  */
30 int zbd_get_zoned_model(struct thread_data *td, struct fio_file *f,
31                         enum zbd_zoned_model *model)
32 {
33         int ret;
34
35         if (td->io_ops && td->io_ops->get_zoned_model)
36                 ret = td->io_ops->get_zoned_model(td, f, model);
37         else
38                 ret = blkzoned_get_zoned_model(td, f, model);
39         if (ret < 0) {
40                 td_verror(td, errno, "get zoned model failed");
41                 log_err("%s: get zoned model failed (%d).\n",
42                         f->file_name, errno);
43         }
44
45         return ret;
46 }
47
48 /**
49  * zbd_report_zones - Get zone information
50  * @td: FIO thread data.
51  * @f: FIO file for which to get zone information
52  * @offset: offset from which to report zones
53  * @zones: Array of struct zbd_zone
54  * @nr_zones: Size of @zones array
55  *
56  * Get zone information into @zones starting from the zone at offset @offset
57  * for the device specified by @f.
58  *
59  * Returns the number of zones reported upon success and a negative error code
60  * upon failure. If the zone report is empty, always assume an error (device
61  * problem) and return -EIO.
62  */
63 int zbd_report_zones(struct thread_data *td, struct fio_file *f,
64                      uint64_t offset, struct zbd_zone *zones,
65                      unsigned int nr_zones)
66 {
67         int ret;
68
69         if (td->io_ops && td->io_ops->report_zones)
70                 ret = td->io_ops->report_zones(td, f, offset, zones, nr_zones);
71         else
72                 ret = blkzoned_report_zones(td, f, offset, zones, nr_zones);
73         if (ret < 0) {
74                 td_verror(td, errno, "report zones failed");
75                 log_err("%s: report zones from sector %llu failed (%d).\n",
76                         f->file_name, (unsigned long long)offset >> 9, errno);
77         } else if (ret == 0) {
78                 td_verror(td, errno, "Empty zone report");
79                 log_err("%s: report zones from sector %llu is empty.\n",
80                         f->file_name, (unsigned long long)offset >> 9);
81                 ret = -EIO;
82         }
83
84         return ret;
85 }
86
87 /**
88  * zbd_reset_wp - reset the write pointer of a range of zones
89  * @td: FIO thread data.
90  * @f: FIO file for which to reset zones
91  * @offset: Starting offset of the first zone to reset
92  * @length: Length of the range of zones to reset
93  *
94  * Reset the write pointer of all zones in the range @offset...@offset+@length.
95  * Returns 0 upon success and a negative error code upon failure.
96  */
97 int zbd_reset_wp(struct thread_data *td, struct fio_file *f,
98                  uint64_t offset, uint64_t length)
99 {
100         int ret;
101
102         if (td->io_ops && td->io_ops->reset_wp)
103                 ret = td->io_ops->reset_wp(td, f, offset, length);
104         else
105                 ret = blkzoned_reset_wp(td, f, offset, length);
106         if (ret < 0) {
107                 td_verror(td, errno, "resetting wp failed");
108                 log_err("%s: resetting wp for %llu sectors at sector %llu failed (%d).\n",
109                         f->file_name, (unsigned long long)length >> 9,
110                         (unsigned long long)offset >> 9, errno);
111         }
112
113         return ret;
114 }
115
116 /**
117  * zbd_get_max_open_zones - Get the maximum number of open zones
118  * @td: FIO thread data
119  * @f: FIO file for which to get max open zones
120  * @max_open_zones: Upon success, result will be stored here.
121  *
122  * A @max_open_zones value set to zero means no limit.
123  *
124  * Returns 0 upon success and a negative error code upon failure.
125  */
126 int zbd_get_max_open_zones(struct thread_data *td, struct fio_file *f,
127                            unsigned int *max_open_zones)
128 {
129         int ret;
130
131         if (td->io_ops && td->io_ops->get_max_open_zones)
132                 ret = td->io_ops->get_max_open_zones(td, f, max_open_zones);
133         else
134                 ret = blkzoned_get_max_open_zones(td, f, max_open_zones);
135         if (ret < 0) {
136                 td_verror(td, errno, "get max open zones failed");
137                 log_err("%s: get max open zones failed (%d).\n",
138                         f->file_name, errno);
139         }
140
141         return ret;
142 }
143
144 /**
145  * zbd_zone_idx - convert an offset into a zone number
146  * @f: file pointer.
147  * @offset: offset in bytes. If this offset is in the first zone_size bytes
148  *          past the disk size then the index of the sentinel is returned.
149  */
150 static uint32_t zbd_zone_idx(const struct fio_file *f, uint64_t offset)
151 {
152         uint32_t zone_idx;
153
154         if (f->zbd_info->zone_size_log2 > 0)
155                 zone_idx = offset >> f->zbd_info->zone_size_log2;
156         else
157                 zone_idx = offset / f->zbd_info->zone_size;
158
159         return min(zone_idx, f->zbd_info->nr_zones);
160 }
161
162 /**
163  * zbd_zone_end - Return zone end location
164  * @z: zone info pointer.
165  */
166 static inline uint64_t zbd_zone_end(const struct fio_zone_info *z)
167 {
168         return (z+1)->start;
169 }
170
171 /**
172  * zbd_zone_capacity_end - Return zone capacity limit end location
173  * @z: zone info pointer.
174  */
175 static inline uint64_t zbd_zone_capacity_end(const struct fio_zone_info *z)
176 {
177         return z->start + z->capacity;
178 }
179
180 /**
181  * zbd_zone_full - verify whether a minimum number of bytes remain in a zone
182  * @f: file pointer.
183  * @z: zone info pointer.
184  * @required: minimum number of bytes that must remain in a zone.
185  *
186  * The caller must hold z->mutex.
187  */
188 static bool zbd_zone_full(const struct fio_file *f, struct fio_zone_info *z,
189                           uint64_t required)
190 {
191         assert((required & 511) == 0);
192
193         return z->has_wp &&
194                 z->wp + required > zbd_zone_capacity_end(z);
195 }
196
197 static void zone_lock(struct thread_data *td, const struct fio_file *f,
198                       struct fio_zone_info *z)
199 {
200         struct zoned_block_device_info *zbd = f->zbd_info;
201         uint32_t nz = z - zbd->zone_info;
202
203         /* A thread should never lock zones outside its working area. */
204         assert(f->min_zone <= nz && nz < f->max_zone);
205
206         assert(z->has_wp);
207
208         /*
209          * Lock the io_u target zone. The zone will be unlocked if io_u offset
210          * is changed or when io_u completes and zbd_put_io() executed.
211          * To avoid multiple jobs doing asynchronous I/Os from deadlocking each
212          * other waiting for zone locks when building an io_u batch, first
213          * only trylock the zone. If the zone is already locked by another job,
214          * process the currently queued I/Os so that I/O progress is made and
215          * zones unlocked.
216          */
217         if (pthread_mutex_trylock(&z->mutex) != 0) {
218                 if (!td_ioengine_flagged(td, FIO_SYNCIO))
219                         io_u_quiesce(td);
220                 pthread_mutex_lock(&z->mutex);
221         }
222 }
223
224 static inline void zone_unlock(struct fio_zone_info *z)
225 {
226         int ret;
227
228         assert(z->has_wp);
229         ret = pthread_mutex_unlock(&z->mutex);
230         assert(!ret);
231 }
232
233 static bool is_valid_offset(const struct fio_file *f, uint64_t offset)
234 {
235         return (uint64_t)(offset - f->file_offset) < f->io_size;
236 }
237
238 static inline struct fio_zone_info *get_zone(const struct fio_file *f,
239                                              unsigned int zone_nr)
240 {
241         return &f->zbd_info->zone_info[zone_nr];
242 }
243
244 /* Verify whether direct I/O is used for all host-managed zoned drives. */
245 static bool zbd_using_direct_io(void)
246 {
247         struct thread_data *td;
248         struct fio_file *f;
249         int i, j;
250
251         for_each_td(td, i) {
252                 if (td->o.odirect || !(td->o.td_ddir & TD_DDIR_WRITE))
253                         continue;
254                 for_each_file(td, f, j) {
255                         if (f->zbd_info &&
256                             f->zbd_info->model == ZBD_HOST_MANAGED)
257                                 return false;
258                 }
259         }
260
261         return true;
262 }
263
264 /* Whether or not the I/O range for f includes one or more sequential zones */
265 static bool zbd_is_seq_job(struct fio_file *f)
266 {
267         uint32_t zone_idx, zone_idx_b, zone_idx_e;
268
269         assert(f->zbd_info);
270         if (f->io_size == 0)
271                 return false;
272         zone_idx_b = zbd_zone_idx(f, f->file_offset);
273         zone_idx_e = zbd_zone_idx(f, f->file_offset + f->io_size - 1);
274         for (zone_idx = zone_idx_b; zone_idx <= zone_idx_e; zone_idx++)
275                 if (get_zone(f, zone_idx)->has_wp)
276                         return true;
277
278         return false;
279 }
280
281 /*
282  * Verify whether offset and size parameters are aligned with zone boundaries.
283  */
284 static bool zbd_verify_sizes(void)
285 {
286         const struct fio_zone_info *z;
287         struct thread_data *td;
288         struct fio_file *f;
289         uint64_t new_offset, new_end;
290         uint32_t zone_idx;
291         int i, j;
292
293         for_each_td(td, i) {
294                 for_each_file(td, f, j) {
295                         if (!f->zbd_info)
296                                 continue;
297                         if (f->file_offset >= f->real_file_size)
298                                 continue;
299                         if (!zbd_is_seq_job(f))
300                                 continue;
301
302                         if (!td->o.zone_size) {
303                                 td->o.zone_size = f->zbd_info->zone_size;
304                                 if (!td->o.zone_size) {
305                                         log_err("%s: invalid 0 zone size\n",
306                                                 f->file_name);
307                                         return false;
308                                 }
309                         } else if (td->o.zone_size != f->zbd_info->zone_size) {
310                                 log_err("%s: job parameter zonesize %llu does not match disk zone size %llu.\n",
311                                         f->file_name, (unsigned long long) td->o.zone_size,
312                                         (unsigned long long) f->zbd_info->zone_size);
313                                 return false;
314                         }
315
316                         if (td->o.zone_skip % td->o.zone_size) {
317                                 log_err("%s: zoneskip %llu is not a multiple of the device zone size %llu.\n",
318                                         f->file_name, (unsigned long long) td->o.zone_skip,
319                                         (unsigned long long) td->o.zone_size);
320                                 return false;
321                         }
322
323                         zone_idx = zbd_zone_idx(f, f->file_offset);
324                         z = get_zone(f, zone_idx);
325                         if ((f->file_offset != z->start) &&
326                             (td->o.td_ddir != TD_DDIR_READ)) {
327                                 new_offset = zbd_zone_end(z);
328                                 if (new_offset >= f->file_offset + f->io_size) {
329                                         log_info("%s: io_size must be at least one zone\n",
330                                                  f->file_name);
331                                         return false;
332                                 }
333                                 log_info("%s: rounded up offset from %llu to %llu\n",
334                                          f->file_name, (unsigned long long) f->file_offset,
335                                          (unsigned long long) new_offset);
336                                 f->io_size -= (new_offset - f->file_offset);
337                                 f->file_offset = new_offset;
338                         }
339                         zone_idx = zbd_zone_idx(f, f->file_offset + f->io_size);
340                         z = get_zone(f, zone_idx);
341                         new_end = z->start;
342                         if ((td->o.td_ddir != TD_DDIR_READ) &&
343                             (f->file_offset + f->io_size != new_end)) {
344                                 if (new_end <= f->file_offset) {
345                                         log_info("%s: io_size must be at least one zone\n",
346                                                  f->file_name);
347                                         return false;
348                                 }
349                                 log_info("%s: rounded down io_size from %llu to %llu\n",
350                                          f->file_name, (unsigned long long) f->io_size,
351                                          (unsigned long long) new_end - f->file_offset);
352                                 f->io_size = new_end - f->file_offset;
353                         }
354                 }
355         }
356
357         return true;
358 }
359
360 static bool zbd_verify_bs(void)
361 {
362         struct thread_data *td;
363         struct fio_file *f;
364         int i, j, k;
365
366         for_each_td(td, i) {
367                 for_each_file(td, f, j) {
368                         uint64_t zone_size;
369
370                         if (!f->zbd_info)
371                                 continue;
372                         zone_size = f->zbd_info->zone_size;
373                         for (k = 0; k < FIO_ARRAY_SIZE(td->o.bs); k++) {
374                                 if (td->o.verify != VERIFY_NONE &&
375                                     zone_size % td->o.bs[k] != 0) {
376                                         log_info("%s: block size %llu is not a divisor of the zone size %llu\n",
377                                                  f->file_name, td->o.bs[k],
378                                                  (unsigned long long)zone_size);
379                                         return false;
380                                 }
381                         }
382                 }
383         }
384         return true;
385 }
386
387 static int ilog2(uint64_t i)
388 {
389         int log = -1;
390
391         while (i) {
392                 i >>= 1;
393                 log++;
394         }
395         return log;
396 }
397
398 /*
399  * Initialize f->zbd_info for devices that are not zoned block devices. This
400  * allows to execute a ZBD workload against a non-ZBD device.
401  */
402 static int init_zone_info(struct thread_data *td, struct fio_file *f)
403 {
404         uint32_t nr_zones;
405         struct fio_zone_info *p;
406         uint64_t zone_size = td->o.zone_size;
407         uint64_t zone_capacity = td->o.zone_capacity;
408         struct zoned_block_device_info *zbd_info = NULL;
409         int i;
410
411         if (zone_size == 0) {
412                 log_err("%s: Specifying the zone size is mandatory for regular block devices with --zonemode=zbd\n\n",
413                         f->file_name);
414                 return 1;
415         }
416
417         if (zone_size < 512) {
418                 log_err("%s: zone size must be at least 512 bytes for --zonemode=zbd\n\n",
419                         f->file_name);
420                 return 1;
421         }
422
423         if (zone_capacity == 0)
424                 zone_capacity = zone_size;
425
426         if (zone_capacity > zone_size) {
427                 log_err("%s: job parameter zonecapacity %llu is larger than zone size %llu\n",
428                         f->file_name, (unsigned long long) td->o.zone_capacity,
429                         (unsigned long long) td->o.zone_size);
430                 return 1;
431         }
432
433         nr_zones = (f->real_file_size + zone_size - 1) / zone_size;
434         zbd_info = scalloc(1, sizeof(*zbd_info) +
435                            (nr_zones + 1) * sizeof(zbd_info->zone_info[0]));
436         if (!zbd_info)
437                 return -ENOMEM;
438
439         mutex_init_pshared(&zbd_info->mutex);
440         zbd_info->refcount = 1;
441         p = &zbd_info->zone_info[0];
442         for (i = 0; i < nr_zones; i++, p++) {
443                 mutex_init_pshared_with_type(&p->mutex,
444                                              PTHREAD_MUTEX_RECURSIVE);
445                 p->start = i * zone_size;
446                 p->wp = p->start;
447                 p->type = ZBD_ZONE_TYPE_SWR;
448                 p->cond = ZBD_ZONE_COND_EMPTY;
449                 p->capacity = zone_capacity;
450                 p->has_wp = 1;
451         }
452         /* a sentinel */
453         p->start = nr_zones * zone_size;
454
455         f->zbd_info = zbd_info;
456         f->zbd_info->zone_size = zone_size;
457         f->zbd_info->zone_size_log2 = is_power_of_2(zone_size) ?
458                 ilog2(zone_size) : 0;
459         f->zbd_info->nr_zones = nr_zones;
460         return 0;
461 }
462
463 /*
464  * Maximum number of zones to report in one operation.
465  */
466 #define ZBD_REPORT_MAX_ZONES    8192U
467
468 /*
469  * Parse the device zone report and store it in f->zbd_info. Must be called
470  * only for devices that are zoned, namely those with a model != ZBD_NONE.
471  */
472 static int parse_zone_info(struct thread_data *td, struct fio_file *f)
473 {
474         int nr_zones, nrz;
475         struct zbd_zone *zones, *z;
476         struct fio_zone_info *p;
477         uint64_t zone_size, offset;
478         struct zoned_block_device_info *zbd_info = NULL;
479         int i, j, ret = -ENOMEM;
480
481         zones = calloc(ZBD_REPORT_MAX_ZONES, sizeof(struct zbd_zone));
482         if (!zones)
483                 goto out;
484
485         nrz = zbd_report_zones(td, f, 0, zones, ZBD_REPORT_MAX_ZONES);
486         if (nrz < 0) {
487                 ret = nrz;
488                 log_info("fio: report zones (offset 0) failed for %s (%d).\n",
489                          f->file_name, -ret);
490                 goto out;
491         }
492
493         zone_size = zones[0].len;
494         nr_zones = (f->real_file_size + zone_size - 1) / zone_size;
495
496         if (td->o.zone_size == 0) {
497                 td->o.zone_size = zone_size;
498         } else if (td->o.zone_size != zone_size) {
499                 log_err("fio: %s job parameter zonesize %llu does not match disk zone size %llu.\n",
500                         f->file_name, (unsigned long long) td->o.zone_size,
501                         (unsigned long long) zone_size);
502                 ret = -EINVAL;
503                 goto out;
504         }
505
506         dprint(FD_ZBD, "Device %s has %d zones of size %llu KB\n", f->file_name,
507                nr_zones, (unsigned long long) zone_size / 1024);
508
509         zbd_info = scalloc(1, sizeof(*zbd_info) +
510                            (nr_zones + 1) * sizeof(zbd_info->zone_info[0]));
511         if (!zbd_info)
512                 goto out;
513         mutex_init_pshared(&zbd_info->mutex);
514         zbd_info->refcount = 1;
515         p = &zbd_info->zone_info[0];
516         for (offset = 0, j = 0; j < nr_zones;) {
517                 z = &zones[0];
518                 for (i = 0; i < nrz; i++, j++, z++, p++) {
519                         mutex_init_pshared_with_type(&p->mutex,
520                                                      PTHREAD_MUTEX_RECURSIVE);
521                         p->start = z->start;
522                         p->capacity = z->capacity;
523                         switch (z->cond) {
524                         case ZBD_ZONE_COND_NOT_WP:
525                         case ZBD_ZONE_COND_FULL:
526                                 p->wp = p->start + p->capacity;
527                                 break;
528                         default:
529                                 assert(z->start <= z->wp);
530                                 assert(z->wp <= z->start + zone_size);
531                                 p->wp = z->wp;
532                                 break;
533                         }
534
535                         switch (z->type) {
536                         case ZBD_ZONE_TYPE_SWR:
537                                 p->has_wp = 1;
538                                 break;
539                         default:
540                                 p->has_wp = 0;
541                         }
542                         p->type = z->type;
543                         p->cond = z->cond;
544
545                         if (j > 0 && p->start != p[-1].start + zone_size) {
546                                 log_info("%s: invalid zone data\n",
547                                          f->file_name);
548                                 ret = -EINVAL;
549                                 goto out;
550                         }
551                 }
552                 z--;
553                 offset = z->start + z->len;
554                 if (j >= nr_zones)
555                         break;
556                 nrz = zbd_report_zones(td, f, offset, zones,
557                                        min((uint32_t)(nr_zones - j),
558                                            ZBD_REPORT_MAX_ZONES));
559                 if (nrz < 0) {
560                         ret = nrz;
561                         log_info("fio: report zones (offset %llu) failed for %s (%d).\n",
562                                  (unsigned long long)offset,
563                                  f->file_name, -ret);
564                         goto out;
565                 }
566         }
567
568         /* a sentinel */
569         zbd_info->zone_info[nr_zones].start = offset;
570
571         f->zbd_info = zbd_info;
572         f->zbd_info->zone_size = zone_size;
573         f->zbd_info->zone_size_log2 = is_power_of_2(zone_size) ?
574                 ilog2(zone_size) : 0;
575         f->zbd_info->nr_zones = nr_zones;
576         zbd_info = NULL;
577         ret = 0;
578
579 out:
580         sfree(zbd_info);
581         free(zones);
582         return ret;
583 }
584
585 static int zbd_set_max_open_zones(struct thread_data *td, struct fio_file *f)
586 {
587         struct zoned_block_device_info *zbd = f->zbd_info;
588         unsigned int max_open_zones;
589         int ret;
590
591         if (zbd->model != ZBD_HOST_MANAGED) {
592                 /* Only host-managed devices have a max open limit */
593                 zbd->max_open_zones = td->o.max_open_zones;
594                 goto out;
595         }
596
597         /* If host-managed, get the max open limit */
598         ret = zbd_get_max_open_zones(td, f, &max_open_zones);
599         if (ret)
600                 return ret;
601
602         if (!max_open_zones) {
603                 /* No device limit */
604                 zbd->max_open_zones = td->o.max_open_zones;
605         } else if (!td->o.max_open_zones) {
606                 /* No user limit. Set limit to device limit */
607                 zbd->max_open_zones = max_open_zones;
608         } else if (td->o.max_open_zones <= max_open_zones) {
609                 /* Both user limit and dev limit. User limit not too large */
610                 zbd->max_open_zones = td->o.max_open_zones;
611         } else {
612                 /* Both user limit and dev limit. User limit too large */
613                 td_verror(td, EINVAL,
614                           "Specified --max_open_zones is too large");
615                 log_err("Specified --max_open_zones (%d) is larger than max (%u)\n",
616                         td->o.max_open_zones, max_open_zones);
617                 return -EINVAL;
618         }
619
620 out:
621         /* Ensure that the limit is not larger than FIO's internal limit */
622         zbd->max_open_zones = min_not_zero(zbd->max_open_zones,
623                                            (uint32_t) ZBD_MAX_OPEN_ZONES);
624         dprint(FD_ZBD, "%s: using max open zones limit: %"PRIu32"\n",
625                f->file_name, zbd->max_open_zones);
626
627         return 0;
628 }
629
630 /*
631  * Allocate zone information and store it into f->zbd_info if zonemode=zbd.
632  *
633  * Returns 0 upon success and a negative error code upon failure.
634  */
635 static int zbd_create_zone_info(struct thread_data *td, struct fio_file *f)
636 {
637         enum zbd_zoned_model zbd_model;
638         int ret;
639
640         assert(td->o.zone_mode == ZONE_MODE_ZBD);
641
642         ret = zbd_get_zoned_model(td, f, &zbd_model);
643         if (ret)
644                 return ret;
645
646         switch (zbd_model) {
647         case ZBD_IGNORE:
648                 return 0;
649         case ZBD_HOST_AWARE:
650         case ZBD_HOST_MANAGED:
651                 ret = parse_zone_info(td, f);
652                 if (ret)
653                         return ret;
654                 break;
655         case ZBD_NONE:
656                 ret = init_zone_info(td, f);
657                 if (ret)
658                         return ret;
659                 break;
660         default:
661                 td_verror(td, EINVAL, "Unsupported zoned model");
662                 log_err("Unsupported zoned model\n");
663                 return -EINVAL;
664         }
665
666         f->zbd_info->model = zbd_model;
667
668         ret = zbd_set_max_open_zones(td, f);
669         if (ret) {
670                 zbd_free_zone_info(f);
671                 return ret;
672         }
673
674         return 0;
675 }
676
677 void zbd_free_zone_info(struct fio_file *f)
678 {
679         uint32_t refcount;
680
681         assert(f->zbd_info);
682
683         pthread_mutex_lock(&f->zbd_info->mutex);
684         refcount = --f->zbd_info->refcount;
685         pthread_mutex_unlock(&f->zbd_info->mutex);
686
687         assert((int32_t)refcount >= 0);
688         if (refcount == 0)
689                 sfree(f->zbd_info);
690         f->zbd_info = NULL;
691 }
692
693 /*
694  * Initialize f->zbd_info.
695  *
696  * Returns 0 upon success and a negative error code upon failure.
697  *
698  * Note: this function can only work correctly if it is called before the first
699  * fio fork() call.
700  */
701 static int zbd_init_zone_info(struct thread_data *td, struct fio_file *file)
702 {
703         struct thread_data *td2;
704         struct fio_file *f2;
705         int i, j, ret;
706
707         for_each_td(td2, i) {
708                 for_each_file(td2, f2, j) {
709                         if (td2 == td && f2 == file)
710                                 continue;
711                         if (!f2->zbd_info ||
712                             strcmp(f2->file_name, file->file_name) != 0)
713                                 continue;
714                         file->zbd_info = f2->zbd_info;
715                         file->zbd_info->refcount++;
716                         return 0;
717                 }
718         }
719
720         ret = zbd_create_zone_info(td, file);
721         if (ret < 0)
722                 td_verror(td, -ret, "zbd_create_zone_info() failed");
723         return ret;
724 }
725
726 static bool zbd_open_zone(struct thread_data *td, const struct fio_file *f,
727                           uint32_t zone_idx);
728 static int zbd_reset_zone(struct thread_data *td, struct fio_file *f,
729                           struct fio_zone_info *z);
730
731 int zbd_init_files(struct thread_data *td)
732 {
733         struct fio_file *f;
734         int i;
735
736         for_each_file(td, f, i) {
737                 if (zbd_init_zone_info(td, f))
738                         return 1;
739         }
740         return 0;
741 }
742
743 void zbd_recalc_options_with_zone_granularity(struct thread_data *td)
744 {
745         struct fio_file *f;
746         int i;
747
748         for_each_file(td, f, i) {
749                 struct zoned_block_device_info *zbd = f->zbd_info;
750                 // zonemode=strided doesn't get per-file zone size.
751                 uint64_t zone_size = zbd ? zbd->zone_size : td->o.zone_size;
752
753                 if (zone_size == 0)
754                         continue;
755
756                 if (td->o.size_nz > 0) {
757                         td->o.size = td->o.size_nz * zone_size;
758                 }
759                 if (td->o.io_size_nz > 0) {
760                         td->o.io_size = td->o.io_size_nz * zone_size;
761                 }
762                 if (td->o.start_offset_nz > 0) {
763                         td->o.start_offset = td->o.start_offset_nz * zone_size;
764                 }
765                 if (td->o.offset_increment_nz > 0) {
766                         td->o.offset_increment = td->o.offset_increment_nz * zone_size;
767                 }
768                 if (td->o.zone_skip_nz > 0) {
769                         td->o.zone_skip = td->o.zone_skip_nz * zone_size;
770                 }
771         }
772 }
773
774 int zbd_setup_files(struct thread_data *td)
775 {
776         struct fio_file *f;
777         int i;
778
779         if (!zbd_using_direct_io()) {
780                 log_err("Using direct I/O is mandatory for writing to ZBD drives\n\n");
781                 return 1;
782         }
783
784         if (!zbd_verify_sizes())
785                 return 1;
786
787         if (!zbd_verify_bs())
788                 return 1;
789
790         for_each_file(td, f, i) {
791                 struct zoned_block_device_info *zbd = f->zbd_info;
792                 struct fio_zone_info *z;
793                 int zi;
794
795                 if (!zbd)
796                         continue;
797
798                 f->min_zone = zbd_zone_idx(f, f->file_offset);
799                 f->max_zone = zbd_zone_idx(f, f->file_offset + f->io_size);
800
801                 /*
802                  * When all zones in the I/O range are conventional, io_size
803                  * can be smaller than zone size, making min_zone the same
804                  * as max_zone. This is why the assert below needs to be made
805                  * conditional.
806                  */
807                 if (zbd_is_seq_job(f))
808                         assert(f->min_zone < f->max_zone);
809
810                 if (td->o.max_open_zones > 0 &&
811                     zbd->max_open_zones != td->o.max_open_zones) {
812                         log_err("Different 'max_open_zones' values\n");
813                         return 1;
814                 }
815                 if (zbd->max_open_zones > ZBD_MAX_OPEN_ZONES) {
816                         log_err("'max_open_zones' value is limited by %u\n", ZBD_MAX_OPEN_ZONES);
817                         return 1;
818                 }
819
820                 for (zi = f->min_zone; zi < f->max_zone; zi++) {
821                         z = &zbd->zone_info[zi];
822                         if (z->cond != ZBD_ZONE_COND_IMP_OPEN &&
823                             z->cond != ZBD_ZONE_COND_EXP_OPEN)
824                                 continue;
825                         if (zbd_open_zone(td, f, zi))
826                                 continue;
827                         /*
828                          * If the number of open zones exceeds specified limits,
829                          * reset all extra open zones.
830                          */
831                         if (zbd_reset_zone(td, f, z) < 0) {
832                                 log_err("Failed to reest zone %d\n", zi);
833                                 return 1;
834                         }
835                 }
836         }
837
838         return 0;
839 }
840
841 static inline unsigned int zbd_zone_nr(const struct fio_file *f,
842                                        struct fio_zone_info *zone)
843 {
844         return zone - f->zbd_info->zone_info;
845 }
846
847 /**
848  * zbd_reset_zone - reset the write pointer of a single zone
849  * @td: FIO thread data.
850  * @f: FIO file associated with the disk for which to reset a write pointer.
851  * @z: Zone to reset.
852  *
853  * Returns 0 upon success and a negative error code upon failure.
854  *
855  * The caller must hold z->mutex.
856  */
857 static int zbd_reset_zone(struct thread_data *td, struct fio_file *f,
858                           struct fio_zone_info *z)
859 {
860         uint64_t offset = z->start;
861         uint64_t length = (z+1)->start - offset;
862         uint64_t data_in_zone = z->wp - z->start;
863         int ret = 0;
864
865         if (!data_in_zone)
866                 return 0;
867
868         assert(is_valid_offset(f, offset + length - 1));
869
870         dprint(FD_ZBD, "%s: resetting wp of zone %u.\n", f->file_name,
871                 zbd_zone_nr(f, z));
872         switch (f->zbd_info->model) {
873         case ZBD_HOST_AWARE:
874         case ZBD_HOST_MANAGED:
875                 ret = zbd_reset_wp(td, f, offset, length);
876                 if (ret < 0)
877                         return ret;
878                 break;
879         default:
880                 break;
881         }
882
883         pthread_mutex_lock(&f->zbd_info->mutex);
884         f->zbd_info->sectors_with_data -= data_in_zone;
885         f->zbd_info->wp_sectors_with_data -= data_in_zone;
886         pthread_mutex_unlock(&f->zbd_info->mutex);
887         z->wp = z->start;
888         z->verify_block = 0;
889
890         td->ts.nr_zone_resets++;
891
892         return ret;
893 }
894
895 /* The caller must hold f->zbd_info->mutex */
896 static void zbd_close_zone(struct thread_data *td, const struct fio_file *f,
897                            unsigned int zone_idx)
898 {
899         uint32_t open_zone_idx = 0;
900
901         for (; open_zone_idx < f->zbd_info->num_open_zones; open_zone_idx++) {
902                 if (f->zbd_info->open_zones[open_zone_idx] == zone_idx)
903                         break;
904         }
905         if (open_zone_idx == f->zbd_info->num_open_zones)
906                 return;
907
908         dprint(FD_ZBD, "%s: closing zone %d\n", f->file_name, zone_idx);
909         memmove(f->zbd_info->open_zones + open_zone_idx,
910                 f->zbd_info->open_zones + open_zone_idx + 1,
911                 (ZBD_MAX_OPEN_ZONES - (open_zone_idx + 1)) *
912                 sizeof(f->zbd_info->open_zones[0]));
913         f->zbd_info->num_open_zones--;
914         td->num_open_zones--;
915         get_zone(f, zone_idx)->open = 0;
916 }
917
918 /*
919  * Reset a range of zones. Returns 0 upon success and 1 upon failure.
920  * @td: fio thread data.
921  * @f: fio file for which to reset zones
922  * @zb: first zone to reset.
923  * @ze: first zone not to reset.
924  */
925 static int zbd_reset_zones(struct thread_data *td, struct fio_file *f,
926                            struct fio_zone_info *const zb,
927                            struct fio_zone_info *const ze)
928 {
929         struct fio_zone_info *z;
930         const uint32_t min_bs = td->o.min_bs[DDIR_WRITE];
931         int res = 0;
932
933         assert(min_bs);
934
935         dprint(FD_ZBD, "%s: examining zones %u .. %u\n", f->file_name,
936                 zbd_zone_nr(f, zb), zbd_zone_nr(f, ze));
937         for (z = zb; z < ze; z++) {
938                 uint32_t nz = zbd_zone_nr(f, z);
939
940                 if (!z->has_wp)
941                         continue;
942                 zone_lock(td, f, z);
943                 pthread_mutex_lock(&f->zbd_info->mutex);
944                 zbd_close_zone(td, f, nz);
945                 pthread_mutex_unlock(&f->zbd_info->mutex);
946                 if (z->wp != z->start) {
947                         dprint(FD_ZBD, "%s: resetting zone %u\n",
948                                f->file_name, zbd_zone_nr(f, z));
949                         if (zbd_reset_zone(td, f, z) < 0)
950                                 res = 1;
951                 }
952                 zone_unlock(z);
953         }
954
955         return res;
956 }
957
958 /*
959  * Reset zbd_info.write_cnt, the counter that counts down towards the next
960  * zone reset.
961  */
962 static void _zbd_reset_write_cnt(const struct thread_data *td,
963                                  const struct fio_file *f)
964 {
965         assert(0 <= td->o.zrf.u.f && td->o.zrf.u.f <= 1);
966
967         f->zbd_info->write_cnt = td->o.zrf.u.f ?
968                 min(1.0 / td->o.zrf.u.f, 0.0 + UINT_MAX) : UINT_MAX;
969 }
970
971 static void zbd_reset_write_cnt(const struct thread_data *td,
972                                 const struct fio_file *f)
973 {
974         pthread_mutex_lock(&f->zbd_info->mutex);
975         _zbd_reset_write_cnt(td, f);
976         pthread_mutex_unlock(&f->zbd_info->mutex);
977 }
978
979 static bool zbd_dec_and_reset_write_cnt(const struct thread_data *td,
980                                         const struct fio_file *f)
981 {
982         uint32_t write_cnt = 0;
983
984         pthread_mutex_lock(&f->zbd_info->mutex);
985         assert(f->zbd_info->write_cnt);
986         if (f->zbd_info->write_cnt)
987                 write_cnt = --f->zbd_info->write_cnt;
988         if (write_cnt == 0)
989                 _zbd_reset_write_cnt(td, f);
990         pthread_mutex_unlock(&f->zbd_info->mutex);
991
992         return write_cnt == 0;
993 }
994
995 enum swd_action {
996         CHECK_SWD,
997         SET_SWD,
998 };
999
1000 /* Calculate the number of sectors with data (swd) and perform action 'a' */
1001 static uint64_t zbd_process_swd(struct thread_data *td,
1002                                 const struct fio_file *f, enum swd_action a)
1003 {
1004         struct fio_zone_info *zb, *ze, *z;
1005         uint64_t swd = 0;
1006         uint64_t wp_swd = 0;
1007
1008         zb = get_zone(f, f->min_zone);
1009         ze = get_zone(f, f->max_zone);
1010         for (z = zb; z < ze; z++) {
1011                 if (z->has_wp) {
1012                         zone_lock(td, f, z);
1013                         wp_swd += z->wp - z->start;
1014                 }
1015                 swd += z->wp - z->start;
1016         }
1017         pthread_mutex_lock(&f->zbd_info->mutex);
1018         switch (a) {
1019         case CHECK_SWD:
1020                 assert(f->zbd_info->sectors_with_data == swd);
1021                 assert(f->zbd_info->wp_sectors_with_data == wp_swd);
1022                 break;
1023         case SET_SWD:
1024                 f->zbd_info->sectors_with_data = swd;
1025                 f->zbd_info->wp_sectors_with_data = wp_swd;
1026                 break;
1027         }
1028         pthread_mutex_unlock(&f->zbd_info->mutex);
1029         for (z = zb; z < ze; z++)
1030                 if (z->has_wp)
1031                         zone_unlock(z);
1032
1033         return swd;
1034 }
1035
1036 /*
1037  * The swd check is useful for debugging but takes too much time to leave
1038  * it enabled all the time. Hence it is disabled by default.
1039  */
1040 static const bool enable_check_swd = false;
1041
1042 /* Check whether the values of zbd_info.*sectors_with_data are correct. */
1043 static void zbd_check_swd(struct thread_data *td, const struct fio_file *f)
1044 {
1045         if (!enable_check_swd)
1046                 return;
1047
1048         zbd_process_swd(td, f, CHECK_SWD);
1049 }
1050
1051 void zbd_file_reset(struct thread_data *td, struct fio_file *f)
1052 {
1053         struct fio_zone_info *zb, *ze;
1054         uint64_t swd;
1055
1056         if (!f->zbd_info || !td_write(td))
1057                 return;
1058
1059         zb = get_zone(f, f->min_zone);
1060         ze = get_zone(f, f->max_zone);
1061         swd = zbd_process_swd(td, f, SET_SWD);
1062         dprint(FD_ZBD, "%s(%s): swd = %" PRIu64 "\n", __func__, f->file_name,
1063                swd);
1064         /*
1065          * If data verification is enabled reset the affected zones before
1066          * writing any data to avoid that a zone reset has to be issued while
1067          * writing data, which causes data loss.
1068          */
1069         if (td->o.verify != VERIFY_NONE && td->runstate != TD_VERIFYING)
1070                 zbd_reset_zones(td, f, zb, ze);
1071         zbd_reset_write_cnt(td, f);
1072 }
1073
1074 /* The caller must hold f->zbd_info->mutex. */
1075 static bool is_zone_open(const struct thread_data *td, const struct fio_file *f,
1076                          unsigned int zone_idx)
1077 {
1078         struct zoned_block_device_info *zbdi = f->zbd_info;
1079         int i;
1080
1081         assert(td->o.job_max_open_zones == 0 || td->num_open_zones <= td->o.job_max_open_zones);
1082         assert(td->o.job_max_open_zones <= zbdi->max_open_zones);
1083         assert(zbdi->num_open_zones <= zbdi->max_open_zones);
1084
1085         for (i = 0; i < zbdi->num_open_zones; i++)
1086                 if (zbdi->open_zones[i] == zone_idx)
1087                         return true;
1088
1089         return false;
1090 }
1091
1092 /*
1093  * Open a ZBD zone if it was not yet open. Returns true if either the zone was
1094  * already open or if opening a new zone is allowed. Returns false if the zone
1095  * was not yet open and opening a new zone would cause the zone limit to be
1096  * exceeded.
1097  */
1098 static bool zbd_open_zone(struct thread_data *td, const struct fio_file *f,
1099                           uint32_t zone_idx)
1100 {
1101         const uint32_t min_bs = td->o.min_bs[DDIR_WRITE];
1102         struct fio_zone_info *z = get_zone(f, zone_idx);
1103         bool res = true;
1104
1105         if (z->cond == ZBD_ZONE_COND_OFFLINE)
1106                 return false;
1107
1108         /*
1109          * Skip full zones with data verification enabled because resetting a
1110          * zone causes data loss and hence causes verification to fail.
1111          */
1112         if (td->o.verify != VERIFY_NONE && zbd_zone_full(f, z, min_bs))
1113                 return false;
1114
1115         pthread_mutex_lock(&f->zbd_info->mutex);
1116         if (is_zone_open(td, f, zone_idx)) {
1117                 /*
1118                  * If the zone is already open and going to be full by writes
1119                  * in-flight, handle it as a full zone instead of an open zone.
1120                  */
1121                 if (z->wp >= zbd_zone_capacity_end(z))
1122                         res = false;
1123                 goto out;
1124         }
1125         res = false;
1126         /* Zero means no limit */
1127         if (td->o.job_max_open_zones > 0 &&
1128             td->num_open_zones >= td->o.job_max_open_zones)
1129                 goto out;
1130         if (f->zbd_info->num_open_zones >= f->zbd_info->max_open_zones)
1131                 goto out;
1132         dprint(FD_ZBD, "%s: opening zone %d\n", f->file_name, zone_idx);
1133         f->zbd_info->open_zones[f->zbd_info->num_open_zones++] = zone_idx;
1134         td->num_open_zones++;
1135         z->open = 1;
1136         res = true;
1137
1138 out:
1139         pthread_mutex_unlock(&f->zbd_info->mutex);
1140         return res;
1141 }
1142
1143 /* Anything goes as long as it is not a constant. */
1144 static uint32_t pick_random_zone_idx(const struct fio_file *f,
1145                                      const struct io_u *io_u)
1146 {
1147         return io_u->offset * f->zbd_info->num_open_zones / f->real_file_size;
1148 }
1149
1150 /*
1151  * Modify the offset of an I/O unit that does not refer to an open zone such
1152  * that it refers to an open zone. Close an open zone and open a new zone if
1153  * necessary. The open zone is searched across sequential zones.
1154  * This algorithm can only work correctly if all write pointers are
1155  * a multiple of the fio block size. The caller must neither hold z->mutex
1156  * nor f->zbd_info->mutex. Returns with z->mutex held upon success.
1157  */
1158 static struct fio_zone_info *zbd_convert_to_open_zone(struct thread_data *td,
1159                                                       struct io_u *io_u)
1160 {
1161         const uint32_t min_bs = td->o.min_bs[io_u->ddir];
1162         struct fio_file *f = io_u->file;
1163         struct fio_zone_info *z;
1164         unsigned int open_zone_idx = -1;
1165         uint32_t zone_idx, new_zone_idx;
1166         int i;
1167         bool wait_zone_close;
1168
1169         assert(is_valid_offset(f, io_u->offset));
1170
1171         if (td->o.max_open_zones || td->o.job_max_open_zones) {
1172                 /*
1173                  * This statement accesses f->zbd_info->open_zones[] on purpose
1174                  * without locking.
1175                  */
1176                 zone_idx = f->zbd_info->open_zones[pick_random_zone_idx(f, io_u)];
1177         } else {
1178                 zone_idx = zbd_zone_idx(f, io_u->offset);
1179         }
1180         if (zone_idx < f->min_zone)
1181                 zone_idx = f->min_zone;
1182         else if (zone_idx >= f->max_zone)
1183                 zone_idx = f->max_zone - 1;
1184         dprint(FD_ZBD, "%s(%s): starting from zone %d (offset %lld, buflen %lld)\n",
1185                __func__, f->file_name, zone_idx, io_u->offset, io_u->buflen);
1186
1187         /*
1188          * Since z->mutex is the outer lock and f->zbd_info->mutex the inner
1189          * lock it can happen that the state of the zone with index zone_idx
1190          * has changed after 'z' has been assigned and before f->zbd_info->mutex
1191          * has been obtained. Hence the loop.
1192          */
1193         for (;;) {
1194                 uint32_t tmp_idx;
1195
1196                 z = get_zone(f, zone_idx);
1197                 if (z->has_wp)
1198                         zone_lock(td, f, z);
1199                 pthread_mutex_lock(&f->zbd_info->mutex);
1200                 if (z->has_wp) {
1201                         if (z->cond != ZBD_ZONE_COND_OFFLINE &&
1202                             td->o.max_open_zones == 0 && td->o.job_max_open_zones == 0)
1203                                 goto examine_zone;
1204                         if (f->zbd_info->num_open_zones == 0) {
1205                                 dprint(FD_ZBD, "%s(%s): no zones are open\n",
1206                                        __func__, f->file_name);
1207                                 goto open_other_zone;
1208                         }
1209                 }
1210
1211                 /*
1212                  * List of opened zones is per-device, shared across all threads.
1213                  * Start with quasi-random candidate zone.
1214                  * Ignore zones which don't belong to thread's offset/size area.
1215                  */
1216                 open_zone_idx = pick_random_zone_idx(f, io_u);
1217                 assert(!open_zone_idx ||
1218                        open_zone_idx < f->zbd_info->num_open_zones);
1219                 tmp_idx = open_zone_idx;
1220                 for (i = 0; i < f->zbd_info->num_open_zones; i++) {
1221                         uint32_t tmpz;
1222
1223                         if (tmp_idx >= f->zbd_info->num_open_zones)
1224                                 tmp_idx = 0;
1225                         tmpz = f->zbd_info->open_zones[tmp_idx];
1226                         if (f->min_zone <= tmpz && tmpz < f->max_zone) {
1227                                 open_zone_idx = tmp_idx;
1228                                 goto found_candidate_zone;
1229                         }
1230
1231                         tmp_idx++;
1232                 }
1233
1234                 dprint(FD_ZBD, "%s(%s): no candidate zone\n",
1235                         __func__, f->file_name);
1236                 pthread_mutex_unlock(&f->zbd_info->mutex);
1237                 if (z->has_wp)
1238                         zone_unlock(z);
1239                 return NULL;
1240
1241 found_candidate_zone:
1242                 new_zone_idx = f->zbd_info->open_zones[open_zone_idx];
1243                 if (new_zone_idx == zone_idx)
1244                         break;
1245                 zone_idx = new_zone_idx;
1246                 pthread_mutex_unlock(&f->zbd_info->mutex);
1247                 if (z->has_wp)
1248                         zone_unlock(z);
1249         }
1250
1251         /* Both z->mutex and f->zbd_info->mutex are held. */
1252
1253 examine_zone:
1254         if (z->wp + min_bs <= zbd_zone_capacity_end(z)) {
1255                 pthread_mutex_unlock(&f->zbd_info->mutex);
1256                 goto out;
1257         }
1258
1259 open_other_zone:
1260         /* Check if number of open zones reaches one of limits. */
1261         wait_zone_close =
1262                 f->zbd_info->num_open_zones == f->max_zone - f->min_zone ||
1263                 (td->o.max_open_zones &&
1264                  f->zbd_info->num_open_zones == td->o.max_open_zones) ||
1265                 (td->o.job_max_open_zones &&
1266                  td->num_open_zones == td->o.job_max_open_zones);
1267
1268         pthread_mutex_unlock(&f->zbd_info->mutex);
1269
1270         /* Only z->mutex is held. */
1271
1272         /*
1273          * When number of open zones reaches to one of limits, wait for
1274          * zone close before opening a new zone.
1275          */
1276         if (wait_zone_close) {
1277                 dprint(FD_ZBD, "%s(%s): quiesce to allow open zones to close\n",
1278                        __func__, f->file_name);
1279                 io_u_quiesce(td);
1280         }
1281
1282         /* Zone 'z' is full, so try to open a new zone. */
1283         for (i = f->io_size / f->zbd_info->zone_size; i > 0; i--) {
1284                 zone_idx++;
1285                 if (z->has_wp)
1286                         zone_unlock(z);
1287                 z++;
1288                 if (!is_valid_offset(f, z->start)) {
1289                         /* Wrap-around. */
1290                         zone_idx = f->min_zone;
1291                         z = get_zone(f, zone_idx);
1292                 }
1293                 assert(is_valid_offset(f, z->start));
1294                 if (!z->has_wp)
1295                         continue;
1296                 zone_lock(td, f, z);
1297                 if (z->open)
1298                         continue;
1299                 if (zbd_open_zone(td, f, zone_idx))
1300                         goto out;
1301         }
1302
1303         /* Only z->mutex is held. */
1304
1305         /* Check whether the write fits in any of the already opened zones. */
1306         pthread_mutex_lock(&f->zbd_info->mutex);
1307         for (i = 0; i < f->zbd_info->num_open_zones; i++) {
1308                 zone_idx = f->zbd_info->open_zones[i];
1309                 if (zone_idx < f->min_zone || zone_idx >= f->max_zone)
1310                         continue;
1311                 pthread_mutex_unlock(&f->zbd_info->mutex);
1312                 zone_unlock(z);
1313
1314                 z = get_zone(f, zone_idx);
1315
1316                 zone_lock(td, f, z);
1317                 if (z->wp + min_bs <= zbd_zone_capacity_end(z))
1318                         goto out;
1319                 pthread_mutex_lock(&f->zbd_info->mutex);
1320         }
1321         pthread_mutex_unlock(&f->zbd_info->mutex);
1322         zone_unlock(z);
1323         dprint(FD_ZBD, "%s(%s): did not open another zone\n", __func__,
1324                f->file_name);
1325         return NULL;
1326
1327 out:
1328         dprint(FD_ZBD, "%s(%s): returning zone %d\n", __func__, f->file_name,
1329                zone_idx);
1330         io_u->offset = z->start;
1331         assert(z->has_wp);
1332         assert(z->cond != ZBD_ZONE_COND_OFFLINE);
1333         return z;
1334 }
1335
1336 /* The caller must hold z->mutex. */
1337 static struct fio_zone_info *zbd_replay_write_order(struct thread_data *td,
1338                                                     struct io_u *io_u,
1339                                                     struct fio_zone_info *z)
1340 {
1341         const struct fio_file *f = io_u->file;
1342         const uint32_t min_bs = td->o.min_bs[DDIR_WRITE];
1343
1344         if (!zbd_open_zone(td, f, zbd_zone_nr(f, z))) {
1345                 zone_unlock(z);
1346                 z = zbd_convert_to_open_zone(td, io_u);
1347                 assert(z);
1348         }
1349
1350         if (z->verify_block * min_bs >= z->capacity) {
1351                 log_err("%s: %d * %d >= %llu\n", f->file_name, z->verify_block,
1352                         min_bs, (unsigned long long)z->capacity);
1353                 /*
1354                  * If the assertion below fails during a test run, adding
1355                  * "--experimental_verify=1" to the command line may help.
1356                  */
1357                 assert(false);
1358         }
1359         io_u->offset = z->start + z->verify_block * min_bs;
1360         if (io_u->offset + io_u->buflen >= zbd_zone_capacity_end(z)) {
1361                 log_err("%s: %llu + %llu >= %llu\n", f->file_name, io_u->offset,
1362                         io_u->buflen, (unsigned long long) zbd_zone_capacity_end(z));
1363                 assert(false);
1364         }
1365         z->verify_block += io_u->buflen / min_bs;
1366
1367         return z;
1368 }
1369
1370 /*
1371  * Find another zone for which @io_u fits in the readable data in the zone.
1372  * Search in zones @zb + 1 .. @zl. For random workload, also search in zones
1373  * @zb - 1 .. @zf.
1374  *
1375  * Either returns NULL or returns a zone pointer. When the zone has write
1376  * pointer, hold the mutex for the zone.
1377  */
1378 static struct fio_zone_info *
1379 zbd_find_zone(struct thread_data *td, struct io_u *io_u,
1380               struct fio_zone_info *zb, struct fio_zone_info *zl)
1381 {
1382         const uint32_t min_bs = td->o.min_bs[io_u->ddir];
1383         struct fio_file *f = io_u->file;
1384         struct fio_zone_info *z1, *z2;
1385         const struct fio_zone_info *const zf = get_zone(f, f->min_zone);
1386
1387         /*
1388          * Skip to the next non-empty zone in case of sequential I/O and to
1389          * the nearest non-empty zone in case of random I/O.
1390          */
1391         for (z1 = zb + 1, z2 = zb - 1; z1 < zl || z2 >= zf; z1++, z2--) {
1392                 if (z1 < zl && z1->cond != ZBD_ZONE_COND_OFFLINE) {
1393                         if (z1->has_wp)
1394                                 zone_lock(td, f, z1);
1395                         if (z1->start + min_bs <= z1->wp)
1396                                 return z1;
1397                         if (z1->has_wp)
1398                                 zone_unlock(z1);
1399                 } else if (!td_random(td)) {
1400                         break;
1401                 }
1402                 if (td_random(td) && z2 >= zf &&
1403                     z2->cond != ZBD_ZONE_COND_OFFLINE) {
1404                         if (z2->has_wp)
1405                                 zone_lock(td, f, z2);
1406                         if (z2->start + min_bs <= z2->wp)
1407                                 return z2;
1408                         if (z2->has_wp)
1409                                 zone_unlock(z2);
1410                 }
1411         }
1412         dprint(FD_ZBD, "%s: adjusting random read offset failed\n",
1413                f->file_name);
1414         return NULL;
1415 }
1416
1417 /**
1418  * zbd_end_zone_io - update zone status at command completion
1419  * @io_u: I/O unit
1420  * @z: zone info pointer
1421  *
1422  * If the write command made the zone full, close it.
1423  *
1424  * The caller must hold z->mutex.
1425  */
1426 static void zbd_end_zone_io(struct thread_data *td, const struct io_u *io_u,
1427                             struct fio_zone_info *z)
1428 {
1429         const struct fio_file *f = io_u->file;
1430
1431         if (io_u->ddir == DDIR_WRITE &&
1432             io_u->offset + io_u->buflen >= zbd_zone_capacity_end(z)) {
1433                 pthread_mutex_lock(&f->zbd_info->mutex);
1434                 zbd_close_zone(td, f, zbd_zone_nr(f, z));
1435                 pthread_mutex_unlock(&f->zbd_info->mutex);
1436         }
1437 }
1438
1439 /**
1440  * zbd_queue_io - update the write pointer of a sequential zone
1441  * @io_u: I/O unit
1442  * @success: Whether or not the I/O unit has been queued successfully
1443  * @q: queueing status (busy, completed or queued).
1444  *
1445  * For write and trim operations, update the write pointer of the I/O unit
1446  * target zone.
1447  */
1448 static void zbd_queue_io(struct thread_data *td, struct io_u *io_u, int q,
1449                          bool success)
1450 {
1451         const struct fio_file *f = io_u->file;
1452         struct zoned_block_device_info *zbd_info = f->zbd_info;
1453         struct fio_zone_info *z;
1454         uint32_t zone_idx;
1455         uint64_t zone_end;
1456
1457         if (!zbd_info)
1458                 return;
1459
1460         zone_idx = zbd_zone_idx(f, io_u->offset);
1461         assert(zone_idx < zbd_info->nr_zones);
1462         z = get_zone(f, zone_idx);
1463
1464         assert(z->has_wp);
1465
1466         if (!success)
1467                 goto unlock;
1468
1469         dprint(FD_ZBD,
1470                "%s: queued I/O (%lld, %llu) for zone %u\n",
1471                f->file_name, io_u->offset, io_u->buflen, zone_idx);
1472
1473         switch (io_u->ddir) {
1474         case DDIR_WRITE:
1475                 zone_end = min((uint64_t)(io_u->offset + io_u->buflen),
1476                                zbd_zone_capacity_end(z));
1477                 pthread_mutex_lock(&zbd_info->mutex);
1478                 /*
1479                  * z->wp > zone_end means that one or more I/O errors
1480                  * have occurred.
1481                  */
1482                 if (z->wp <= zone_end) {
1483                         zbd_info->sectors_with_data += zone_end - z->wp;
1484                         zbd_info->wp_sectors_with_data += zone_end - z->wp;
1485                 }
1486                 pthread_mutex_unlock(&zbd_info->mutex);
1487                 z->wp = zone_end;
1488                 break;
1489         case DDIR_TRIM:
1490                 assert(z->wp == z->start);
1491                 break;
1492         default:
1493                 break;
1494         }
1495
1496         if (q == FIO_Q_COMPLETED && !io_u->error)
1497                 zbd_end_zone_io(td, io_u, z);
1498
1499 unlock:
1500         if (!success || q != FIO_Q_QUEUED) {
1501                 /* BUSY or COMPLETED: unlock the zone */
1502                 zone_unlock(z);
1503                 io_u->zbd_put_io = NULL;
1504         }
1505 }
1506
1507 /**
1508  * zbd_put_io - Unlock an I/O unit target zone lock
1509  * @io_u: I/O unit
1510  */
1511 static void zbd_put_io(struct thread_data *td, const struct io_u *io_u)
1512 {
1513         const struct fio_file *f = io_u->file;
1514         struct zoned_block_device_info *zbd_info = f->zbd_info;
1515         struct fio_zone_info *z;
1516         uint32_t zone_idx;
1517
1518         if (!zbd_info)
1519                 return;
1520
1521         zone_idx = zbd_zone_idx(f, io_u->offset);
1522         assert(zone_idx < zbd_info->nr_zones);
1523         z = get_zone(f, zone_idx);
1524
1525         assert(z->has_wp);
1526
1527         dprint(FD_ZBD,
1528                "%s: terminate I/O (%lld, %llu) for zone %u\n",
1529                f->file_name, io_u->offset, io_u->buflen, zone_idx);
1530
1531         zbd_end_zone_io(td, io_u, z);
1532
1533         zone_unlock(z);
1534         zbd_check_swd(td, f);
1535 }
1536
1537 /*
1538  * Windows and MacOS do not define this.
1539  */
1540 #ifndef EREMOTEIO
1541 #define EREMOTEIO       121     /* POSIX value */
1542 #endif
1543
1544 bool zbd_unaligned_write(int error_code)
1545 {
1546         switch (error_code) {
1547         case EIO:
1548         case EREMOTEIO:
1549                 return true;
1550         }
1551         return false;
1552 }
1553
1554 /**
1555  * setup_zbd_zone_mode - handle zoneskip as necessary for ZBD drives
1556  * @td: FIO thread data.
1557  * @io_u: FIO I/O unit.
1558  *
1559  * For sequential workloads, change the file offset to skip zoneskip bytes when
1560  * no more IO can be performed in the current zone.
1561  * - For read workloads, zoneskip is applied when the io has reached the end of
1562  *   the zone or the zone write position (when td->o.read_beyond_wp is false).
1563  * - For write workloads, zoneskip is applied when the zone is full.
1564  * This applies only to read and write operations.
1565  */
1566 void setup_zbd_zone_mode(struct thread_data *td, struct io_u *io_u)
1567 {
1568         struct fio_file *f = io_u->file;
1569         enum fio_ddir ddir = io_u->ddir;
1570         struct fio_zone_info *z;
1571         uint32_t zone_idx;
1572
1573         assert(td->o.zone_mode == ZONE_MODE_ZBD);
1574         assert(td->o.zone_size);
1575
1576         zone_idx = zbd_zone_idx(f, f->last_pos[ddir]);
1577         z = get_zone(f, zone_idx);
1578
1579         /*
1580          * When the zone capacity is smaller than the zone size and the I/O is
1581          * sequential write, skip to zone end if the latest position is at the
1582          * zone capacity limit.
1583          */
1584         if (z->capacity < f->zbd_info->zone_size && !td_random(td) &&
1585             ddir == DDIR_WRITE &&
1586             f->last_pos[ddir] >= zbd_zone_capacity_end(z)) {
1587                 dprint(FD_ZBD,
1588                        "%s: Jump from zone capacity limit to zone end:"
1589                        " (%llu -> %llu) for zone %u (%llu)\n",
1590                        f->file_name, (unsigned long long) f->last_pos[ddir],
1591                        (unsigned long long) zbd_zone_end(z), zone_idx,
1592                        (unsigned long long) z->capacity);
1593                 td->io_skip_bytes += zbd_zone_end(z) - f->last_pos[ddir];
1594                 f->last_pos[ddir] = zbd_zone_end(z);
1595         }
1596
1597         /*
1598          * zone_skip is valid only for sequential workloads.
1599          */
1600         if (td_random(td) || !td->o.zone_skip)
1601                 return;
1602
1603         /*
1604          * It is time to switch to a new zone if:
1605          * - zone_bytes == zone_size bytes have already been accessed
1606          * - The last position reached the end of the current zone.
1607          * - For reads with td->o.read_beyond_wp == false, the last position
1608          *   reached the zone write pointer.
1609          */
1610         if (td->zone_bytes >= td->o.zone_size ||
1611             f->last_pos[ddir] >= zbd_zone_end(z) ||
1612             (ddir == DDIR_READ &&
1613              (!td->o.read_beyond_wp) && f->last_pos[ddir] >= z->wp)) {
1614                 /*
1615                  * Skip zones.
1616                  */
1617                 td->zone_bytes = 0;
1618                 f->file_offset += td->o.zone_size + td->o.zone_skip;
1619
1620                 /*
1621                  * Wrap from the beginning, if we exceed the file size
1622                  */
1623                 if (f->file_offset >= f->real_file_size)
1624                         f->file_offset = get_start_offset(td, f);
1625
1626                 f->last_pos[ddir] = f->file_offset;
1627                 td->io_skip_bytes += td->o.zone_skip;
1628         }
1629 }
1630
1631 /**
1632  * zbd_adjust_ddir - Adjust an I/O direction for zonemode=zbd.
1633  *
1634  * @td: FIO thread data.
1635  * @io_u: FIO I/O unit.
1636  * @ddir: I/O direction before adjustment.
1637  *
1638  * Return adjusted I/O direction.
1639  */
1640 enum fio_ddir zbd_adjust_ddir(struct thread_data *td, struct io_u *io_u,
1641                               enum fio_ddir ddir)
1642 {
1643         /*
1644          * In case read direction is chosen for the first random I/O, fio with
1645          * zonemode=zbd stops because no data can be read from zoned block
1646          * devices with all empty zones. Overwrite the first I/O direction as
1647          * write to make sure data to read exists.
1648          */
1649         if (ddir != DDIR_READ || !td_rw(td))
1650                 return ddir;
1651
1652         if (io_u->file->zbd_info->sectors_with_data ||
1653             td->o.read_beyond_wp)
1654                 return DDIR_READ;
1655
1656         return DDIR_WRITE;
1657 }
1658
1659 /**
1660  * zbd_adjust_block - adjust the offset and length as necessary for ZBD drives
1661  * @td: FIO thread data.
1662  * @io_u: FIO I/O unit.
1663  *
1664  * Locking strategy: returns with z->mutex locked if and only if z refers
1665  * to a sequential zone and if io_u_accept is returned. z is the zone that
1666  * corresponds to io_u->offset at the end of this function.
1667  */
1668 enum io_u_action zbd_adjust_block(struct thread_data *td, struct io_u *io_u)
1669 {
1670         struct fio_file *f = io_u->file;
1671         uint32_t zone_idx_b;
1672         struct fio_zone_info *zb, *zl, *orig_zb;
1673         uint32_t orig_len = io_u->buflen;
1674         uint32_t min_bs = td->o.min_bs[io_u->ddir];
1675         uint64_t new_len;
1676         int64_t range;
1677
1678         if (!f->zbd_info)
1679                 return io_u_accept;
1680
1681         assert(min_bs);
1682         assert(is_valid_offset(f, io_u->offset));
1683         assert(io_u->buflen);
1684         zone_idx_b = zbd_zone_idx(f, io_u->offset);
1685         zb = get_zone(f, zone_idx_b);
1686         orig_zb = zb;
1687
1688         if (!zb->has_wp) {
1689                 /* Accept non-write I/Os for conventional zones. */
1690                 if (io_u->ddir != DDIR_WRITE)
1691                         return io_u_accept;
1692                 /*
1693                  * Make sure that writes to conventional zones
1694                  * don't cross over to any sequential zones.
1695                  */
1696                 if (!(zb + 1)->has_wp ||
1697                     io_u->offset + io_u->buflen <= (zb + 1)->start)
1698                         return io_u_accept;
1699
1700                 if (io_u->offset + min_bs > (zb + 1)->start) {
1701                         dprint(FD_IO,
1702                                "%s: off=%llu + min_bs=%u > next zone %llu\n",
1703                                f->file_name, io_u->offset,
1704                                min_bs, (unsigned long long) (zb + 1)->start);
1705                         io_u->offset = zb->start + (zb + 1)->start - io_u->offset;
1706                         new_len = min(io_u->buflen, (zb + 1)->start - io_u->offset);
1707                 } else {
1708                         new_len = (zb + 1)->start - io_u->offset;
1709                 }
1710                 io_u->buflen = new_len / min_bs * min_bs;
1711                 return io_u_accept;
1712         }
1713
1714         /*
1715          * Accept the I/O offset for reads if reading beyond the write pointer
1716          * is enabled.
1717          */
1718         if (zb->cond != ZBD_ZONE_COND_OFFLINE &&
1719             io_u->ddir == DDIR_READ && td->o.read_beyond_wp)
1720                 return io_u_accept;
1721
1722         zbd_check_swd(td, f);
1723
1724         zone_lock(td, f, zb);
1725
1726         switch (io_u->ddir) {
1727         case DDIR_READ:
1728                 if (td->runstate == TD_VERIFYING && td_write(td)) {
1729                         zb = zbd_replay_write_order(td, io_u, zb);
1730                         goto accept;
1731                 }
1732                 /*
1733                  * Check that there is enough written data in the zone to do an
1734                  * I/O of at least min_bs B. If there isn't, find a new zone for
1735                  * the I/O.
1736                  */
1737                 range = zb->cond != ZBD_ZONE_COND_OFFLINE ?
1738                         zb->wp - zb->start : 0;
1739                 if (range < min_bs ||
1740                     ((!td_random(td)) && (io_u->offset + min_bs > zb->wp))) {
1741                         zone_unlock(zb);
1742                         zl = get_zone(f, f->max_zone);
1743                         zb = zbd_find_zone(td, io_u, zb, zl);
1744                         if (!zb) {
1745                                 dprint(FD_ZBD,
1746                                        "%s: zbd_find_zone(%lld, %llu) failed\n",
1747                                        f->file_name, io_u->offset,
1748                                        io_u->buflen);
1749                                 goto eof;
1750                         }
1751                         /*
1752                          * zbd_find_zone() returned a zone with a range of at
1753                          * least min_bs.
1754                          */
1755                         range = zb->wp - zb->start;
1756                         assert(range >= min_bs);
1757
1758                         if (!td_random(td))
1759                                 io_u->offset = zb->start;
1760                 }
1761                 /*
1762                  * Make sure the I/O is within the zone valid data range while
1763                  * maximizing the I/O size and preserving randomness.
1764                  */
1765                 if (range <= io_u->buflen)
1766                         io_u->offset = zb->start;
1767                 else if (td_random(td))
1768                         io_u->offset = zb->start +
1769                                 ((io_u->offset - orig_zb->start) %
1770                                  (range - io_u->buflen)) / min_bs * min_bs;
1771                 /*
1772                  * When zbd_find_zone() returns a conventional zone,
1773                  * we can simply accept the new i/o offset here.
1774                  */
1775                 if (!zb->has_wp)
1776                         return io_u_accept;
1777                 /*
1778                  * Make sure the I/O does not cross over the zone wp position.
1779                  */
1780                 new_len = min((unsigned long long)io_u->buflen,
1781                               (unsigned long long)(zb->wp - io_u->offset));
1782                 new_len = new_len / min_bs * min_bs;
1783                 if (new_len < io_u->buflen) {
1784                         io_u->buflen = new_len;
1785                         dprint(FD_IO, "Changed length from %u into %llu\n",
1786                                orig_len, io_u->buflen);
1787                 }
1788                 assert(zb->start <= io_u->offset);
1789                 assert(io_u->offset + io_u->buflen <= zb->wp);
1790                 goto accept;
1791         case DDIR_WRITE:
1792                 if (io_u->buflen > f->zbd_info->zone_size) {
1793                         td_verror(td, EINVAL, "I/O buflen exceeds zone size");
1794                         dprint(FD_IO,
1795                                "%s: I/O buflen %llu exceeds zone size %llu\n",
1796                                f->file_name, io_u->buflen,
1797                                (unsigned long long) f->zbd_info->zone_size);
1798                         goto eof;
1799                 }
1800                 if (!zbd_open_zone(td, f, zone_idx_b)) {
1801                         zone_unlock(zb);
1802                         zb = zbd_convert_to_open_zone(td, io_u);
1803                         if (!zb) {
1804                                 dprint(FD_IO, "%s: can't convert to open zone",
1805                                        f->file_name);
1806                                 goto eof;
1807                         }
1808                         zone_idx_b = zbd_zone_nr(f, zb);
1809                 }
1810                 /* Check whether the zone reset threshold has been exceeded */
1811                 if (td->o.zrf.u.f) {
1812                         if (f->zbd_info->wp_sectors_with_data >=
1813                             f->io_size * td->o.zrt.u.f &&
1814                             zbd_dec_and_reset_write_cnt(td, f)) {
1815                                 zb->reset_zone = 1;
1816                         }
1817                 }
1818                 /* Reset the zone pointer if necessary */
1819                 if (zb->reset_zone || zbd_zone_full(f, zb, min_bs)) {
1820                         assert(td->o.verify == VERIFY_NONE);
1821                         /*
1822                          * Since previous write requests may have been submitted
1823                          * asynchronously and since we will submit the zone
1824                          * reset synchronously, wait until previously submitted
1825                          * write requests have completed before issuing a
1826                          * zone reset.
1827                          */
1828                         io_u_quiesce(td);
1829                         zb->reset_zone = 0;
1830                         if (zbd_reset_zone(td, f, zb) < 0)
1831                                 goto eof;
1832
1833                         if (zb->capacity < min_bs) {
1834                                 td_verror(td, EINVAL, "ZCAP is less min_bs");
1835                                 log_err("zone capacity %llu smaller than minimum block size %d\n",
1836                                         (unsigned long long)zb->capacity,
1837                                         min_bs);
1838                                 goto eof;
1839                         }
1840                 }
1841                 /* Make writes occur at the write pointer */
1842                 assert(!zbd_zone_full(f, zb, min_bs));
1843                 io_u->offset = zb->wp;
1844                 if (!is_valid_offset(f, io_u->offset)) {
1845                         td_verror(td, EINVAL, "invalid WP value");
1846                         dprint(FD_ZBD, "%s: dropped request with offset %llu\n",
1847                                f->file_name, io_u->offset);
1848                         goto eof;
1849                 }
1850                 /*
1851                  * Make sure that the buflen is a multiple of the minimal
1852                  * block size. Give up if shrinking would make the request too
1853                  * small.
1854                  */
1855                 new_len = min((unsigned long long)io_u->buflen,
1856                               zbd_zone_capacity_end(zb) - io_u->offset);
1857                 new_len = new_len / min_bs * min_bs;
1858                 if (new_len == io_u->buflen)
1859                         goto accept;
1860                 if (new_len >= min_bs) {
1861                         io_u->buflen = new_len;
1862                         dprint(FD_IO, "Changed length from %u into %llu\n",
1863                                orig_len, io_u->buflen);
1864                         goto accept;
1865                 }
1866                 td_verror(td, EIO, "zone remainder too small");
1867                 log_err("zone remainder %lld smaller than min block size %d\n",
1868                         (zbd_zone_capacity_end(zb) - io_u->offset), min_bs);
1869                 goto eof;
1870         case DDIR_TRIM:
1871                 /* fall-through */
1872         case DDIR_SYNC:
1873         case DDIR_DATASYNC:
1874         case DDIR_SYNC_FILE_RANGE:
1875         case DDIR_WAIT:
1876         case DDIR_LAST:
1877         case DDIR_INVAL:
1878                 goto accept;
1879         }
1880
1881         assert(false);
1882
1883 accept:
1884         assert(zb->has_wp);
1885         assert(zb->cond != ZBD_ZONE_COND_OFFLINE);
1886         assert(!io_u->zbd_queue_io);
1887         assert(!io_u->zbd_put_io);
1888         io_u->zbd_queue_io = zbd_queue_io;
1889         io_u->zbd_put_io = zbd_put_io;
1890         /*
1891          * Since we return with the zone lock still held,
1892          * add an annotation to let Coverity know that it
1893          * is intentional.
1894          */
1895         /* coverity[missing_unlock] */
1896         return io_u_accept;
1897
1898 eof:
1899         if (zb && zb->has_wp)
1900                 zone_unlock(zb);
1901         return io_u_eof;
1902 }
1903
1904 /* Return a string with ZBD statistics */
1905 char *zbd_write_status(const struct thread_stat *ts)
1906 {
1907         char *res;
1908
1909         if (asprintf(&res, "; %llu zone resets", (unsigned long long) ts->nr_zone_resets) < 0)
1910                 return NULL;
1911         return res;
1912 }