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