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