To support zone finish operation to ZBC drives through libzbc, add finish_zone() callback to struct ioengine_ops, and implement in libzbc IO engine. This feature is used to keep the same zone handling by zonemode=zbd for libzbc engine as other engines. Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@xxxxxxx> Tested-by: Dmitry Fomichev <dmitry.fomichev@xxxxxxx> Reviewed-by: Dmitry Fomichev <dmitry.fomichev@xxxxxxx> --- engines/libzbc.c | 34 ++++++++++++++++++++++++++++++++++ ioengines.h | 2 ++ 2 files changed, 36 insertions(+) diff --git a/engines/libzbc.c b/engines/libzbc.c index 2bc2c7e0..2b63ef1a 100644 --- a/engines/libzbc.c +++ b/engines/libzbc.c @@ -332,6 +332,39 @@ err: return -ret; } +static int libzbc_finish_zone(struct thread_data *td, struct fio_file *f, + uint64_t offset, uint64_t length) +{ + struct libzbc_data *ld = td->io_ops_data; + uint64_t sector = offset >> 9; + unsigned int nr_zones; + struct zbc_errno err; + int i, ret; + + assert(ld); + assert(ld->zdev); + + nr_zones = (length + td->o.zone_size - 1) / td->o.zone_size; + assert(nr_zones > 0); + + for (i = 0; i < nr_zones; i++, sector += td->o.zone_size >> 9) { + ret = zbc_finish_zone(ld->zdev, sector, 0); + if (ret) + goto err; + } + + return 0; + +err: + zbc_errno(ld->zdev, &err); + td_verror(td, errno, "zbc_finish_zone failed"); + if (err.sk) + log_err("%s: finish zone failed %s:%s\n", + f->file_name, + zbc_sk_str(err.sk), zbc_asc_ascq_str(err.asc_ascq)); + return -ret; +} + static int libzbc_get_max_open_zones(struct thread_data *td, struct fio_file *f, unsigned int *max_open_zones) { @@ -434,6 +467,7 @@ FIO_STATIC struct ioengine_ops ioengine = { .report_zones = libzbc_report_zones, .reset_wp = libzbc_reset_wp, .get_max_open_zones = libzbc_get_max_open_zones, + .finish_zone = libzbc_finish_zone, .queue = libzbc_queue, .flags = FIO_SYNCIO | FIO_NOEXTEND | FIO_RAWIO, }; diff --git a/ioengines.h b/ioengines.h index fafa1e48..11d2115c 100644 --- a/ioengines.h +++ b/ioengines.h @@ -61,6 +61,8 @@ struct ioengine_ops { uint64_t, uint64_t); int (*get_max_open_zones)(struct thread_data *, struct fio_file *, unsigned int *); + int (*finish_zone)(struct thread_data *, struct fio_file *, + uint64_t, uint64_t); int option_struct_size; struct fio_option *options; }; -- 2.37.1