+static int fio_ioring_cmd_close_file(struct thread_data *td,
+ struct fio_file *f)
+{
+ struct ioring_data *ld = td->io_ops_data;
+ struct ioring_options *o = td->eo;
+
+ if (o->cmd_type == FIO_URING_CMD_NVME) {
+ struct nvme_data *data = FILE_ENG_DATA(f);
+
+ FILE_SET_ENG_DATA(f, NULL);
+ free(data);
+ }
+ if (!ld || !o->registerfiles)
+ return generic_close_file(td, f);
+
+ f->fd = -1;
+ return 0;
+}
+
+static int fio_ioring_cmd_get_file_size(struct thread_data *td,
+ struct fio_file *f)
+{
+ struct ioring_options *o = td->eo;
+
+ if (fio_file_size_known(f))
+ return 0;
+
+ if (o->cmd_type == FIO_URING_CMD_NVME) {
+ struct nvme_data *data = NULL;
+ unsigned int nsid, lba_size = 0;
+ __u32 ms = 0;
+ __u64 nlba = 0;
+ int ret;
+
+ ret = fio_nvme_get_info(f, &nsid, &lba_size, &ms, &nlba);
+ if (ret)
+ return ret;
+
+ data = calloc(1, sizeof(struct nvme_data));
+ data->nsid = nsid;
+ if (ms)
+ data->lba_ext = lba_size + ms;
+ else
+ data->lba_shift = ilog2(lba_size);
+
+ f->real_file_size = lba_size * nlba;
+ fio_file_set_size_known(f);
+
+ FILE_SET_ENG_DATA(f, data);
+ return 0;
+ }
+ return generic_get_file_size(td, f);
+}
+
+static int fio_ioring_cmd_get_zoned_model(struct thread_data *td,
+ struct fio_file *f,
+ enum zbd_zoned_model *model)
+{
+ return fio_nvme_get_zoned_model(td, f, model);
+}
+
+static int fio_ioring_cmd_report_zones(struct thread_data *td,
+ struct fio_file *f, uint64_t offset,
+ struct zbd_zone *zbdz,
+ unsigned int nr_zones)
+{
+ return fio_nvme_report_zones(td, f, offset, zbdz, nr_zones);
+}
+
+static int fio_ioring_cmd_reset_wp(struct thread_data *td, struct fio_file *f,
+ uint64_t offset, uint64_t length)
+{
+ return fio_nvme_reset_wp(td, f, offset, length);
+}
+
+static int fio_ioring_cmd_get_max_open_zones(struct thread_data *td,
+ struct fio_file *f,
+ unsigned int *max_open_zones)
+{
+ return fio_nvme_get_max_open_zones(td, f, max_open_zones);
+}
+
+static int fio_ioring_cmd_fetch_ruhs(struct thread_data *td, struct fio_file *f,
+ struct fio_ruhs_info *fruhs_info)
+{
+ struct nvme_fdp_ruh_status *ruhs;
+ int bytes, ret, i;
+
+ bytes = sizeof(*ruhs) + FDP_MAX_RUHS * sizeof(struct nvme_fdp_ruh_status_desc);
+ ruhs = scalloc(1, bytes);
+ if (!ruhs)
+ return -ENOMEM;
+
+ ret = fio_nvme_iomgmt_ruhs(td, f, ruhs, bytes);
+ if (ret)
+ goto free;
+
+ fruhs_info->nr_ruhs = le16_to_cpu(ruhs->nruhsd);
+ for (i = 0; i < fruhs_info->nr_ruhs; i++)
+ fruhs_info->plis[i] = le16_to_cpu(ruhs->ruhss[i].pid);
+free:
+ sfree(ruhs);
+ return ret;
+}
+
+static struct ioengine_ops ioengine_uring = {