On Fri, 2022-10-21 at 15:34 +0900, Shin'ichiro Kawasaki wrote: > 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 <shinichiro.kawasaki@xxxxxxx> Looks good. Tested-by: Dmitry Fomichev <dmitry.fomichev@xxxxxxx> Reviewed-by: Dmitry Fomichev <dmitry.fomichev@xxxxxxx> > --- > 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 > +}