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