smalloc: move to size_t for allocations
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index a4f378d811dd87df2481db8756ee463306e44f9e..b049b61853fdfbd305ad01d857046be88dc68671 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -15,7 +15,7 @@ struct io_completion_data {
        int nr;                         /* input */
 
        int error;                      /* output */
-       unsigned long bytes_done[2];    /* output */
+       unsigned long bytes_done[DDIR_RWDIR_CNT];       /* output */
        struct timeval time;            /* output */
 };
 
@@ -256,7 +256,7 @@ static int get_next_seq_offset(struct thread_data *td, struct fio_file *f,
 {
        assert(ddir_rw(ddir));
 
-       if (f->last_pos >= f->io_size && td->o.time_based)
+       if (f->last_pos >= f->io_size + get_start_offset(td) && td->o.time_based)
                f->last_pos = f->last_pos - f->io_size;
 
        if (f->last_pos < f->real_file_size) {
@@ -377,7 +377,7 @@ static inline int io_u_fits(struct thread_data *td, struct io_u *io_u,
 {
        struct fio_file *f = io_u->file;
 
-       return io_u->offset + buflen <= f->io_size + td->o.start_offset;
+       return io_u->offset + buflen <= f->io_size + get_start_offset(td);
 }
 
 static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u)
@@ -543,6 +543,8 @@ static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir)
        if (td_rw(td) && __should_check_rate(td, odir))
                td->rate_pending_usleep[odir] -= usec;
 
+       if (ddir_trim(ddir))
+               return ddir;
        return ddir;
 }
 
@@ -599,8 +601,10 @@ static enum fio_ddir get_rw_ddir(struct thread_data *td)
                ddir = td->rwmix_ddir;
        } else if (td_read(td))
                ddir = DDIR_READ;
-       else
+       else if (td_write(td))
                ddir = DDIR_WRITE;
+       else
+               ddir = DDIR_TRIM;
 
        td->rwmix_ddir = rate_ddir(td, ddir);
        return td->rwmix_ddir;
@@ -1092,7 +1096,7 @@ again:
 
                io_u->error = 0;
                flist_del(&io_u->list);
-               flist_add(&io_u->list, &td->io_u_busylist);
+               flist_add_tail(&io_u->list, &td->io_u_busylist);
                td->cur_depth++;
                io_u->flags |= IO_U_F_IN_CUR_DEPTH;
        } else if (td->o.verify_async) {
@@ -1286,10 +1290,12 @@ err_put:
 
 void io_u_log_error(struct thread_data *td, struct io_u *io_u)
 {
+       enum error_type_bit eb = td_error_type(io_u->ddir, io_u->error);
        const char *msg[] = { "read", "write", "sync", "datasync",
                                "sync_file_range", "wait", "trim" };
 
-
+       if (td_non_fatal_error(td, eb, io_u->error) && !td->o.error_dump)
+               return;
 
        log_err("fio: io_u error");
 
@@ -1319,6 +1325,13 @@ static void account_io_completion(struct thread_data *td, struct io_u *io_u,
 
                tusec = utime_since(&io_u->start_time, &icd->time);
                add_lat_sample(td, idx, tusec, bytes);
+
+               if (td->o.max_latency && tusec > td->o.max_latency) {
+                       if (!td->error)
+                               log_err("fio: latency of %lu usec exceeds specified max (%u usec)\n", tusec, td->o.max_latency);
+                       td_verror(td, ETIME, "max latency exceeded");
+                       icd->error = ETIME;
+               }
        }
 
        if (!td->o.disable_clat) {
@@ -1381,7 +1394,9 @@ static void io_completed(struct thread_data *td, struct io_u *io_u,
                td->io_blocks[idx]++;
                td->this_io_blocks[idx]++;
                td->io_bytes[idx] += bytes;
-               td->this_io_bytes[idx] += bytes;
+
+               if (!(io_u->flags & IO_U_F_VER_LIST))
+                       td->this_io_bytes[idx] += bytes;
 
                if (idx == DDIR_WRITE) {
                        f = io_u->file;
@@ -1404,7 +1419,7 @@ static void io_completed(struct thread_data *td, struct io_u *io_u,
                                        (usec_for_io(td, idx) -
                                         utime_since_now(&td->start));
                        }
-                       if (__should_check_rate(td, odx))
+                       if (idx != DDIR_TRIM && __should_check_rate(td, odx))
                                td->rate_pending_usleep[odx] =
                                        (usec_for_io(td, odx) -
                                         utime_since_now(&td->start));
@@ -1426,8 +1441,10 @@ static void io_completed(struct thread_data *td, struct io_u *io_u,
                icd->error = io_u->error;
                io_u_log_error(td, io_u);
        }
-       if (icd->error && td_non_fatal_error(icd->error) &&
-           (td->o.continue_on_error & td_error_type(io_u->ddir, icd->error))) {
+       if (icd->error) {
+               enum error_type_bit eb = td_error_type(io_u->ddir, icd->error);
+               if (!td_non_fatal_error(td, eb, icd->error))
+                       return;
                /*
                 * If there is a non_fatal error, then add to the error count
                 * and clear all the errors.
@@ -1442,13 +1459,15 @@ static void io_completed(struct thread_data *td, struct io_u *io_u,
 static void init_icd(struct thread_data *td, struct io_completion_data *icd,
                     int nr)
 {
+       int ddir;
        if (!td->o.disable_clat || !td->o.disable_bw)
                fio_gettime(&icd->time, NULL);
 
        icd->nr = nr;
 
        icd->error = 0;
-       icd->bytes_done[0] = icd->bytes_done[1] = 0;
+       for (ddir = DDIR_READ; ddir < DDIR_RWDIR_CNT; ddir++)
+               icd->bytes_done[ddir] = 0;
 }
 
 static void ios_completed(struct thread_data *td,
@@ -1487,8 +1506,10 @@ int io_u_sync_complete(struct thread_data *td, struct io_u *io_u,
        }
 
        if (bytes) {
-               bytes[0] += icd.bytes_done[0];
-               bytes[1] += icd.bytes_done[1];
+               int ddir;
+
+               for (ddir = DDIR_READ; ddir < DDIR_RWDIR_CNT; ddir++)
+                       bytes[ddir] += icd.bytes_done[ddir];
        }
 
        return 0;
@@ -1525,8 +1546,10 @@ int io_u_queued_complete(struct thread_data *td, int min_evts,
        }
 
        if (bytes) {
-               bytes[0] += icd.bytes_done[0];
-               bytes[1] += icd.bytes_done[1];
+               int ddir;
+
+               for (ddir = DDIR_READ; ddir < DDIR_RWDIR_CNT; ddir++)
+                       bytes[ddir] += icd.bytes_done[ddir];
        }
 
        return 0;