sg: Clean up handling of big endian data fields
[fio.git] / zbd.c
diff --git a/zbd.c b/zbd.c
index 7728f71d25a5b71175e662b4445c94013da19fc1..9b603b97b18344b5e17baf31f199371a8c5f11ff 100644 (file)
--- a/zbd.c
+++ b/zbd.c
@@ -228,12 +228,45 @@ static enum blk_zoned_model get_zbd_model(const char *file_name)
        char *zoned_attr_path = NULL;
        char *model_str = NULL;
        struct stat statbuf;
+       char *sys_devno_path = NULL;
+       char *part_attr_path = NULL;
+       char *part_str = NULL;
+       char sys_path[PATH_MAX];
+       ssize_t sz;
+       char *delim = NULL;
 
        if (stat(file_name, &statbuf) < 0)
                goto out;
-       if (asprintf(&zoned_attr_path, "/sys/dev/block/%d:%d/queue/zoned",
+
+       if (asprintf(&sys_devno_path, "/sys/dev/block/%d:%d",
                     major(statbuf.st_rdev), minor(statbuf.st_rdev)) < 0)
                goto out;
+
+       sz = readlink(sys_devno_path, sys_path, sizeof(sys_path) - 1);
+       if (sz < 0)
+               goto out;
+       sys_path[sz] = '\0';
+
+       /*
+        * If the device is a partition device, cut the device name in the
+        * canonical sysfs path to obtain the sysfs path of the holder device.
+        *   e.g.:  /sys/devices/.../sda/sda1 -> /sys/devices/.../sda
+        */
+       if (asprintf(&part_attr_path, "/sys/dev/block/%s/partition",
+                    sys_path) < 0)
+               goto out;
+       part_str = read_file(part_attr_path);
+       if (part_str && *part_str == '1') {
+               delim = strrchr(sys_path, '/');
+               if (!delim)
+                       goto out;
+               *delim = '\0';
+       }
+
+       if (asprintf(&zoned_attr_path,
+                    "/sys/dev/block/%s/queue/zoned", sys_path) < 0)
+               goto out;
+
        model_str = read_file(zoned_attr_path);
        if (!model_str)
                goto out;
@@ -246,6 +279,9 @@ static enum blk_zoned_model get_zbd_model(const char *file_name)
 out:
        free(model_str);
        free(zoned_attr_path);
+       free(part_str);
+       free(part_attr_path);
+       free(sys_devno_path);
        return model;
 }
 
@@ -726,10 +762,14 @@ static bool zbd_dec_and_reset_write_cnt(const struct thread_data *td,
        return write_cnt == 0;
 }
 
-/* Check whether the value of zbd_info.sectors_with_data is correct. */
-static void zbd_check_swd(const struct fio_file *f)
+enum swd_action {
+       CHECK_SWD,
+       SET_SWD,
+};
+
+/* Calculate the number of sectors with data (swd) and perform action 'a' */
+static uint64_t zbd_process_swd(const struct fio_file *f, enum swd_action a)
 {
-#if 0
        struct fio_zone_info *zb, *ze, *z;
        uint64_t swd = 0;
 
@@ -741,18 +781,49 @@ static void zbd_check_swd(const struct fio_file *f)
                swd += z->wp - z->start;
        }
        pthread_mutex_lock(&f->zbd_info->mutex);
-       assert(f->zbd_info->sectors_with_data == swd);
+       switch (a) {
+       case CHECK_SWD:
+               assert(f->zbd_info->sectors_with_data == swd);
+               break;
+       case SET_SWD:
+               f->zbd_info->sectors_with_data = swd;
+               break;
+       }
        pthread_mutex_unlock(&f->zbd_info->mutex);
        for (z = zb; z < ze; z++)
                pthread_mutex_unlock(&z->mutex);
-#endif
+
+       return swd;
+}
+
+/*
+ * The swd check is useful for debugging but takes too much time to leave
+ * it enabled all the time. Hence it is disabled by default.
+ */
+static const bool enable_check_swd = false;
+
+/* Check whether the value of zbd_info.sectors_with_data is correct. */
+static void zbd_check_swd(const struct fio_file *f)
+{
+       if (!enable_check_swd)
+               return;
+
+       zbd_process_swd(f, CHECK_SWD);
+}
+
+static void zbd_init_swd(struct fio_file *f)
+{
+       uint64_t swd;
+
+       swd = zbd_process_swd(f, SET_SWD);
+       dprint(FD_ZBD, "%s(%s): swd = %" PRIu64 "\n", __func__, f->file_name,
+              swd);
 }
 
 void zbd_file_reset(struct thread_data *td, struct fio_file *f)
 {
-       struct fio_zone_info *zb, *ze, *z;
+       struct fio_zone_info *zb, *ze;
        uint32_t zone_idx_e;
-       uint64_t swd = 0;
 
        if (!f->zbd_info)
                return;
@@ -760,17 +831,7 @@ void zbd_file_reset(struct thread_data *td, struct fio_file *f)
        zb = &f->zbd_info->zone_info[zbd_zone_idx(f, f->file_offset)];
        zone_idx_e = zbd_zone_idx(f, f->file_offset + f->io_size);
        ze = &f->zbd_info->zone_info[zone_idx_e];
-       for (z = zb ; z < ze; z++) {
-               pthread_mutex_lock(&z->mutex);
-               swd += z->wp - z->start;
-       }
-       pthread_mutex_lock(&f->zbd_info->mutex);
-       f->zbd_info->sectors_with_data = swd;
-       pthread_mutex_unlock(&f->zbd_info->mutex);
-       for (z = zb ; z < ze; z++)
-               pthread_mutex_unlock(&z->mutex);
-       dprint(FD_ZBD, "%s(%s): swd = %llu\n", __func__, f->file_name,
-               (unsigned long long) swd);
+       zbd_init_swd(f);
        /*
         * If data verification is enabled reset the affected zones before
         * writing any data to avoid that a zone reset has to be issued while