docs: add warning to per_job_logs option
[fio.git] / zbd.c
diff --git a/zbd.c b/zbd.c
index 7fcf1ec432cfcf8bbaecb1232049037a8bbcead0..c4f7b12f75aaa67ed6fb4f9c369b88d042a1e24b 100644 (file)
--- a/zbd.c
+++ b/zbd.c
@@ -11,6 +11,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include "compiler/compiler.h"
 #include "os/os.h"
 #include "file.h"
 #include "fio.h"
@@ -102,13 +103,13 @@ static bool zbd_zone_full(const struct fio_file *f, struct fio_zone_info *z,
 static void zone_lock(struct thread_data *td, const struct fio_file *f,
                      struct fio_zone_info *z)
 {
+#ifndef NDEBUG
        struct zoned_block_device_info *zbd = f->zbd_info;
-       uint32_t nz = z - zbd->zone_info;
-
+       uint32_t const nz = z - zbd->zone_info;
        /* A thread should never lock zones outside its working area. */
        assert(f->min_zone <= nz && nz < f->max_zone);
-
        assert(z->has_wp);
+#endif
 
        /*
         * Lock the io_u target zone. The zone will be unlocked if io_u offset
@@ -128,11 +129,8 @@ static void zone_lock(struct thread_data *td, const struct fio_file *f,
 
 static inline void zone_unlock(struct fio_zone_info *z)
 {
-       int ret;
-
        assert(z->has_wp);
-       ret = pthread_mutex_unlock(&z->mutex);
-       assert(!ret);
+       pthread_mutex_unlock(&z->mutex);
 }
 
 static inline struct fio_zone_info *zbd_get_zone(const struct fio_file *f,
@@ -420,7 +418,8 @@ static int zbd_reset_zones(struct thread_data *td, struct fio_file *f,
        const uint64_t min_bs = td->o.min_bs[DDIR_WRITE];
        int res = 0;
 
-       assert(min_bs);
+       if (fio_unlikely(0 == min_bs))
+               return 1;
 
        dprint(FD_ZBD, "%s: examining zones %u .. %u\n",
               f->file_name, zbd_zone_idx(f, zb), zbd_zone_idx(f, ze));
@@ -472,6 +471,34 @@ static int zbd_get_max_open_zones(struct thread_data *td, struct fio_file *f,
        return ret;
 }
 
+/**
+ * zbd_get_max_active_zones - Get the maximum number of active zones
+ * @td: FIO thread data
+ * @f: FIO file for which to get max active zones
+ *
+ * Returns max_active_zones limit value of the target file if it is available.
+ * Otherwise return zero, which means no limit.
+ */
+static unsigned int zbd_get_max_active_zones(struct thread_data *td,
+                                            struct fio_file *f)
+{
+       unsigned int max_active_zones;
+       int ret;
+
+       if (td->io_ops && td->io_ops->get_max_active_zones)
+               ret = td->io_ops->get_max_active_zones(td, f,
+                                                      &max_active_zones);
+       else
+               ret = blkzoned_get_max_active_zones(td, f, &max_active_zones);
+       if (ret < 0) {
+               dprint(FD_ZBD, "%s: max_active_zones is not available\n",
+                      f->file_name);
+               return 0;
+       }
+
+       return max_active_zones;
+}
+
 /**
  * __zbd_write_zone_get - Add a zone to the array of write zones.
  * @td: fio thread data.
@@ -928,6 +955,7 @@ static int parse_zone_info(struct thread_data *td, struct fio_file *f)
        f->zbd_info->zone_size_log2 = is_power_of_2(zone_size) ?
                ilog2(zone_size) : 0;
        f->zbd_info->nr_zones = nr_zones;
+       f->zbd_info->max_active_zones = zbd_get_max_active_zones(td, f);
 
        if (same_zone_cap)
                dprint(FD_ZBD, "Zone capacity = %"PRIu64" KB\n",
@@ -1248,7 +1276,11 @@ int zbd_setup_files(struct thread_data *td)
                for (zi = f->min_zone; zi < f->max_zone; zi++) {
                        z = &zbd->zone_info[zi];
                        if (z->cond != ZBD_ZONE_COND_IMP_OPEN &&
-                           z->cond != ZBD_ZONE_COND_EXP_OPEN)
+                           z->cond != ZBD_ZONE_COND_EXP_OPEN &&
+                           z->cond != ZBD_ZONE_COND_CLOSED)
+                               continue;
+                       if (!zbd->max_active_zones &&
+                           z->cond == ZBD_ZONE_COND_CLOSED)
                                continue;
                        if (__zbd_write_zone_get(td, f, z))
                                continue;
@@ -1714,10 +1746,9 @@ unlock:
 static void zbd_put_io(struct thread_data *td, const struct io_u *io_u)
 {
        const struct fio_file *f = io_u->file;
-       struct zoned_block_device_info *zbd_info = f->zbd_info;
        struct fio_zone_info *z;
 
-       assert(zbd_info);
+       assert(f->zbd_info);
 
        z = zbd_offset_to_zone(f, io_u->offset);
        assert(z->has_wp);
@@ -2140,6 +2171,7 @@ retry:
        case DDIR_WAIT:
        case DDIR_LAST:
        case DDIR_INVAL:
+       case DDIR_TIMEOUT:
                goto accept;
        }
 
@@ -2212,3 +2244,15 @@ int zbd_do_io_u_trim(struct thread_data *td, struct io_u *io_u)
 
        return io_u_completed;
 }
+
+void zbd_log_err(const struct thread_data *td, const struct io_u *io_u)
+{
+       const struct fio_file *f = io_u->file;
+
+       if (td->o.zone_mode != ZONE_MODE_ZBD)
+               return;
+
+       if (io_u->error == EOVERFLOW)
+               log_err("%s: Exceeded max_active_zones limit. Check conditions of zones out of I/O ranges.\n",
+                       f->file_name);
+}