- * conditional.
- */
- if (zbd_is_seq_job(f))
- assert(f->min_zone < f->max_zone);
-
- if (td->o.max_open_zones > 0 &&
- zbd->max_open_zones != td->o.max_open_zones) {
- log_err("Different 'max_open_zones' values\n");
- return 1;
- }
-
- /*
- * The per job max open zones limit cannot be used without a
- * global max open zones limit. (As the tracking of open zones
- * is disabled when there is no global max open zones limit.)
- */
- if (td->o.job_max_open_zones && !zbd->max_open_zones) {
- log_err("'job_max_open_zones' cannot be used without a global open zones limit\n");
- return 1;
- }
-
- /*
- * zbd->max_open_zones is the global limit shared for all jobs
- * that target the same zoned block device. Force sync the per
- * thread global limit with the actual global limit. (The real
- * per thread/job limit is stored in td->o.job_max_open_zones).
- */
- td->o.max_open_zones = zbd->max_open_zones;
-
- for (zi = f->min_zone; zi < f->max_zone; zi++) {
- z = &zbd->zone_info[zi];
- if (z->cond != ZBD_ZONE_COND_IMP_OPEN &&
- z->cond != ZBD_ZONE_COND_EXP_OPEN)
- continue;
- if (zbd_open_zone(td, f, zi))
- continue;
- /*
- * If the number of open zones exceeds specified limits,
- * reset all extra open zones.
- */
- if (zbd_reset_zone(td, f, z) < 0) {
- log_err("Failed to reest zone %d\n", zi);
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-static inline unsigned int zbd_zone_nr(const struct fio_file *f,
- struct fio_zone_info *zone)
-{
- return zone - f->zbd_info->zone_info;
-}
-
-/**
- * zbd_reset_zone - reset the write pointer of a single zone
- * @td: FIO thread data.
- * @f: FIO file associated with the disk for which to reset a write pointer.
- * @z: Zone to reset.
- *
- * Returns 0 upon success and a negative error code upon failure.
- *
- * The caller must hold z->mutex.
- */
-static int zbd_reset_zone(struct thread_data *td, struct fio_file *f,
- struct fio_zone_info *z)
-{
- uint64_t offset = z->start;
- uint64_t length = (z+1)->start - offset;
- uint64_t data_in_zone = z->wp - z->start;
- int ret = 0;
-
- if (!data_in_zone)
- return 0;
-
- assert(is_valid_offset(f, offset + length - 1));
-
- dprint(FD_ZBD, "%s: resetting wp of zone %u.\n", f->file_name,
- zbd_zone_nr(f, z));
- switch (f->zbd_info->model) {
- case ZBD_HOST_AWARE:
- case ZBD_HOST_MANAGED:
- ret = zbd_reset_wp(td, f, offset, length);
- if (ret < 0)
- return ret;
- break;
- default:
- break;
- }
-
- pthread_mutex_lock(&f->zbd_info->mutex);
- f->zbd_info->sectors_with_data -= data_in_zone;
- f->zbd_info->wp_sectors_with_data -= data_in_zone;
- pthread_mutex_unlock(&f->zbd_info->mutex);
- z->wp = z->start;
- z->verify_block = 0;
-
- td->ts.nr_zone_resets++;
-
- return ret;
-}
-
-/* The caller must hold f->zbd_info->mutex */
-static void zbd_close_zone(struct thread_data *td, const struct fio_file *f,
- unsigned int zone_idx)
-{
- uint32_t open_zone_idx = 0;
-
- for (; open_zone_idx < f->zbd_info->num_open_zones; open_zone_idx++) {
- if (f->zbd_info->open_zones[open_zone_idx] == zone_idx)
- break;
- }
- if (open_zone_idx == f->zbd_info->num_open_zones)
- return;
-
- dprint(FD_ZBD, "%s: closing zone %d\n", f->file_name, zone_idx);
- memmove(f->zbd_info->open_zones + open_zone_idx,
- f->zbd_info->open_zones + open_zone_idx + 1,
- (ZBD_MAX_OPEN_ZONES - (open_zone_idx + 1)) *
- sizeof(f->zbd_info->open_zones[0]));
- f->zbd_info->num_open_zones--;
- td->num_open_zones--;
- get_zone(f, zone_idx)->open = 0;
-}