From f8ec93e47b97fed10951f9ef2aaa6a84750b713a Mon Sep 17 00:00:00 2001 From: Shin'ichiro Kawasaki Date: Mon, 14 Nov 2022 11:12:56 +0900 Subject: [PATCH] oslib: blkzoned: add blkzoned_finish_zone() helper function Add the helper function blkzoned_finish_zone() to support zone finish operation to zoned block devices through ioctl. This feature will be used to change status of zones which is not yet full but does not have enough size to write next block, so that such zones do not exceed max active zones limit. This function does zone finish only when kernel supports the ioctl BLKFINISHZONE. Otherwise, it does nothing. This should be fine since the kernel without BLKFINISHZONE does not report max active zone limit through sysfs to user space. Signed-off-by: Shin'ichiro Kawasaki Tested-by: Dmitry Fomichev Reviewed-by: Dmitry Fomichev Signed-off-by: Vincent Fu --- oslib/blkzoned.h | 8 ++++++++ oslib/linux-blkzoned.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/oslib/blkzoned.h b/oslib/blkzoned.h index 719b041d..29fb034f 100644 --- a/oslib/blkzoned.h +++ b/oslib/blkzoned.h @@ -18,6 +18,8 @@ extern int blkzoned_reset_wp(struct thread_data *td, struct fio_file *f, uint64_t offset, uint64_t length); extern int blkzoned_get_max_open_zones(struct thread_data *td, struct fio_file *f, unsigned int *max_open_zones); +extern int blkzoned_finish_zone(struct thread_data *td, struct fio_file *f, + uint64_t offset, uint64_t length); #else /* * Define stubs for systems that do not have zoned block device support. @@ -51,6 +53,12 @@ static inline int blkzoned_get_max_open_zones(struct thread_data *td, struct fio { return -EIO; } +static inline int blkzoned_finish_zone(struct thread_data *td, + struct fio_file *f, + uint64_t offset, uint64_t length) +{ + return -EIO; +} #endif #endif /* FIO_BLKZONED_H */ diff --git a/oslib/linux-blkzoned.c b/oslib/linux-blkzoned.c index 185bd501..c3130d0e 100644 --- a/oslib/linux-blkzoned.c +++ b/oslib/linux-blkzoned.c @@ -308,3 +308,40 @@ int blkzoned_reset_wp(struct thread_data *td, struct fio_file *f, return ret; } + +int blkzoned_finish_zone(struct thread_data *td, struct fio_file *f, + uint64_t offset, uint64_t length) +{ +#ifdef BLKFINISHZONE + struct blk_zone_range zr = { + .sector = offset >> 9, + .nr_sectors = length >> 9, + }; + int fd, ret = 0; + + /* If the file is not yet opened, open it for this function. */ + fd = f->fd; + if (fd < 0) { + fd = open(f->file_name, O_RDWR | O_LARGEFILE); + if (fd < 0) + return -errno; + } + + if (ioctl(fd, BLKFINISHZONE, &zr) < 0) + ret = -errno; + + if (f->fd < 0) + close(fd); + + return ret; +#else + /* + * Kernel versions older than 5.5 does not support BLKFINISHZONE. These + * old kernels assumed zones are closed automatically at max_open_zones + * limit. Also they did not support max_active_zones limit. Then there + * was no need to finish zones to avoid errors caused by max_open_zones + * or max_active_zones. For those old versions, just do nothing. + */ + return 0; +#endif +} -- 2.25.1