Fix file unlinking
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index 1f9ebbc83bd61da39947274130aef529bc5708e0..a171ee4be8998cfd07612ea79bc6d854dbfcc3f3 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -52,7 +52,11 @@ static void mark_random_map(struct thread_data *td, struct io_u *io_u)
        while (blocks < nr_blocks) {
                unsigned int idx, bit;
 
-               if (!random_map_free(td, f, block))
+               /*
+                * If we have a mixed random workload, we may
+                * encounter blocks we already did IO to.
+                */
+               if (!td->o.ddir_nr && !random_map_free(td, f, block))
                        break;
 
                idx = RAND_MAP_IDX(td, f, block);
@@ -109,6 +113,15 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u)
                unsigned long long max_blocks = f->file_size / td->o.min_bs[ddir];
                int loops = 5;
 
+               if (td->o.ddir_nr) {
+                       if (!--td->ddir_nr)
+                               td->ddir_nr = td->o.ddir_nr;
+                       else {
+                               b = f->last_pos / td->o.min_bs[ddir];
+                               goto out;
+                       }
+               }
+
                do {
                        r = os_random_long(&td->random_state);
                        if (!max_blocks)
@@ -130,6 +143,7 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u)
        } else
                b = f->last_pos / td->o.min_bs[ddir];
 
+out:
        io_u->offset = (b * td->o.min_bs[ddir]) + f->file_offset;
        if (io_u->offset >= f->real_file_size)
                return 1;
@@ -235,8 +249,13 @@ static enum fio_ddir get_rw_ddir(struct thread_data *td)
                         */
                        ddir = get_rand_ddir(td);
                        max_bytes = td->this_io_bytes[ddir];
-                       if (max_bytes >= (td->io_size * td->o.rwmix[ddir] / 100))
+                       if (max_bytes >= (td->io_size * td->o.rwmix[ddir] / 100)) {
+                               if (!td->rw_end_set[ddir]) {
+                                       td->rw_end_set[ddir] = 1;
+                                       memcpy(&td->rw_end[ddir], &now, sizeof(now));
+                               }
                                ddir ^= 1;
+                       }
 
                        if (ddir != td->rwmix_ddir)
                                set_rwmix_bytes(td);
@@ -706,12 +725,10 @@ long io_u_queued_complete(struct thread_data *td, int min_events)
        struct io_completion_data icd;
        struct timespec *tvp = NULL;
        int ret;
+       struct timespec ts = { .tv_sec = 0, .tv_nsec = 0, };
 
-       if (!min_events) {
-               struct timespec ts = { .tv_sec = 0, .tv_nsec = 0, };
-
+       if (!min_events)
                tvp = &ts;
-       }
 
        ret = td_io_getevents(td, min_events, td->cur_depth, tvp);
        if (ret < 0) {