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