Improve mixed random append option
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index 2b18e9f8a9a606c349304d843156f2b9a26025d0..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;