oslib: blkzoned: add blkzoned_finish_zone() helper function
authorShin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Mon, 14 Nov 2022 02:12:56 +0000 (11:12 +0900)
committerVincent Fu <vincent.fu@samsung.com>
Fri, 18 Nov 2022 14:55:16 +0000 (09:55 -0500)
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@wdc.com>
Tested-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
Signed-off-by: Vincent Fu <vincent.fu@samsung.com>
oslib/blkzoned.h
oslib/linux-blkzoned.c

index 719b041d126adc03af9e30b9d2c9815b804a4518..29fb034f585402b3798609b32a18c0519c9a03f5 100644 (file)
@@ -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 */
index 185bd5011bbc5105e7bf67a171b0d93a93727ae2..c3130d0e2a1b2d9d98a1914e80cb591969364e4b 100644 (file)
@@ -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
+}