backend: fix potential divide-by-zero
[fio.git] / backend.c
index 12c76d8545ef53a02b95223ca8d53237b3175ef4..c1c8f96774850a755681dffa710d0ee1550fe16b 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -57,7 +57,6 @@
 static pthread_t disk_util_thread;
 static struct fio_mutex *disk_thread_mutex;
 static struct fio_mutex *startup_mutex;
-static struct fio_mutex *writeout_mutex;
 static struct flist_head *cgroup_list;
 static char *cgroup_mnt;
 static int exit_value;
@@ -183,7 +182,11 @@ static int __check_min_rate(struct thread_data *td, struct timeval *now,
                                                                ratemin);
                                return 1;
                        } else {
-                               rate = ((bytes - td->rate_bytes[ddir]) * 1000) / spent;
+                               if (spent)
+                                       rate = ((bytes - td->rate_bytes[ddir]) * 1000) / spent;
+                               else
+                                       rate = 0;
+
                                if (rate < ratemin ||
                                    bytes < td->rate_bytes[ddir]) {
                                        log_err("%s: min rate %u not met, got"
@@ -623,6 +626,19 @@ reap:
        dprint(FD_VERIFY, "exiting loop\n");
 }
 
+static unsigned int exceeds_number_ios(struct thread_data *td)
+{
+       unsigned long long number_ios;
+
+       if (!td->o.number_ios)
+               return 0;
+
+       number_ios = ddir_rw_sum(td->this_io_blocks);
+       number_ios += td->io_u_queued + td->io_u_in_flight;
+
+       return number_ios >= td->o.number_ios;
+}
+
 static int io_bytes_exceeded(struct thread_data *td)
 {
        unsigned long long bytes;
@@ -636,7 +652,7 @@ static int io_bytes_exceeded(struct thread_data *td)
        else
                bytes = td->this_io_bytes[DDIR_TRIM];
 
-       return bytes >= td->o.size;
+       return bytes >= td->o.size || exceeds_number_ios(td);
 }
 
 /*
@@ -1098,7 +1114,8 @@ static int switch_ioscheduler(struct thread_data *td)
        /*
         * Read back and check that the selected scheduler is now the default.
         */
-       ret = fread(tmp, 1, sizeof(tmp), f);
+       memset(tmp, 0, sizeof(tmp));
+       ret = fread(tmp, 1, sizeof(tmp) - 1, f);
        if (ferror(f) || ret < 0) {
                td_verror(td, errno, "fread");
                fclose(f);
@@ -1127,6 +1144,8 @@ static int keep_running(struct thread_data *td)
                td->o.loops--;
                return 1;
        }
+       if (exceeds_number_ios(td))
+               return 0;
 
        if (td->o.size != -1ULL && ddir_rw_sum(td->io_bytes) < td->o.size) {
                uint64_t diff;
@@ -1196,6 +1215,12 @@ static uint64_t do_dry_run(struct thread_data *td)
                        td->ts.total_io_u[io_u->ddir]++;
                }
 
+               if (td_write(td) && io_u->ddir == DDIR_WRITE &&
+                   td->o.do_verify &&
+                   td->o.verify != VERIFY_NONE &&
+                   !td->o.experimental_verify)
+                       log_io_piece(td, io_u);
+
                ret = io_u_sync_complete(td, io_u, bytes_done);
                (void) ret;
        }
@@ -1279,7 +1304,7 @@ static void *thread_main(void *data)
         */
        if (o->cpumask_set) {
                if (o->cpus_allowed_policy == FIO_CPUS_SPLIT) {
-                       ret = fio_cpus_split(&o->cpumask, td->thread_number);
+                       ret = fio_cpus_split(&o->cpumask, td->thread_number - 1);
                        if (!ret) {
                                log_err("fio: no CPUs set\n");
                                log_err("fio: Try increasing number of available CPUs\n");
@@ -1469,45 +1494,8 @@ static void *thread_main(void *data)
 
        fio_unpin_memory(td);
 
-       fio_mutex_down(writeout_mutex);
-       finalize_logs(td);
-       if (td->bw_log) {
-               if (o->bw_log_file) {
-                       finish_log_named(td, td->bw_log,
-                                               o->bw_log_file, "bw");
-               } else
-                       finish_log(td, td->bw_log, "bw");
-       }
-       if (td->lat_log) {
-               if (o->lat_log_file) {
-                       finish_log_named(td, td->lat_log,
-                                               o->lat_log_file, "lat");
-               } else
-                       finish_log(td, td->lat_log, "lat");
-       }
-       if (td->slat_log) {
-               if (o->lat_log_file) {
-                       finish_log_named(td, td->slat_log,
-                                               o->lat_log_file, "slat");
-               } else
-                       finish_log(td, td->slat_log, "slat");
-       }
-       if (td->clat_log) {
-               if (o->lat_log_file) {
-                       finish_log_named(td, td->clat_log,
-                                               o->lat_log_file, "clat");
-               } else
-                       finish_log(td, td->clat_log, "clat");
-       }
-       if (td->iops_log) {
-               if (o->iops_log_file) {
-                       finish_log_named(td, td->iops_log,
-                                               o->iops_log_file, "iops");
-               } else
-                       finish_log(td, td->iops_log, "iops");
-       }
+       fio_writeout_logs(td);
 
-       fio_mutex_up(writeout_mutex);
        if (o->exec_postrun)
                exec_string(o, o->exec_postrun, (const char *)"postrun");
 
@@ -2012,9 +2000,6 @@ int fio_backend(void)
        startup_mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
        if (startup_mutex == NULL)
                return 1;
-       writeout_mutex = fio_mutex_init(FIO_MUTEX_UNLOCKED);
-       if (writeout_mutex == NULL)
-               return 1;
 
        set_genesis_time();
        stat_init();
@@ -2045,7 +2030,6 @@ int fio_backend(void)
        sfree(cgroup_mnt);
 
        fio_mutex_remove(startup_mutex);
-       fio_mutex_remove(writeout_mutex);
        fio_mutex_remove(disk_thread_mutex);
        stat_exit();
        return exit_value;