Merge branch 'fio-issue-450' of https://github.com/gvkovai/fio
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index 852b98e9d0f5a5c30a3f886fd29ca11b1b074c42..1d6872edb2876794e9c4c07d5ea5e05a726f34dd 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -922,6 +922,45 @@ void requeue_io_u(struct thread_data *td, struct io_u **io_u)
        *io_u = NULL;
 }
 
+static void __fill_io_u_zone(struct thread_data *td, struct io_u *io_u)
+{
+       struct fio_file *f = io_u->file;
+
+       /*
+        * See if it's time to switch to a new zone
+        */
+       if (td->zone_bytes >= td->o.zone_size && td->o.zone_skip) {
+               td->zone_bytes = 0;
+               f->file_offset += td->o.zone_range + td->o.zone_skip;
+
+               /*
+                * Wrap from the beginning, if we exceed the file size
+                */
+               if (f->file_offset >= f->real_file_size)
+                       f->file_offset = f->real_file_size - f->file_offset;
+               f->last_pos[io_u->ddir] = f->file_offset;
+               td->io_skip_bytes += td->o.zone_skip;
+       }
+
+       /*
+        * If zone_size > zone_range, then maintain the same zone until
+        * zone_bytes >= zone_size.
+        */
+       if (f->last_pos[io_u->ddir] >= (f->file_offset + td->o.zone_range)) {
+               dprint(FD_IO, "io_u maintain zone offset=%" PRIu64 "/last_pos=%" PRIu64 "\n",
+                               f->file_offset, f->last_pos[io_u->ddir]);
+               f->last_pos[io_u->ddir] = f->file_offset;
+       }
+
+       /*
+        * For random: if 'norandommap' is not set and zone_size > zone_range,
+        * map needs to be reset as it's done with zone_range everytime.
+        */
+       if ((td->zone_bytes % td->o.zone_range) == 0) {
+               fio_file_reset(td, f);
+       }
+}
+
 static int fill_io_u(struct thread_data *td, struct io_u *io_u)
 {
        unsigned int is_random;
@@ -938,21 +977,10 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u)
                goto out;
 
        /*
-        * See if it's time to switch to a new zone
+        * When file is zoned zone_range is always positive
         */
-       if (td->zone_bytes >= td->o.zone_size && td->o.zone_skip) {
-               struct fio_file *f = io_u->file;
-
-               td->zone_bytes = 0;
-               f->file_offset += td->o.zone_range + td->o.zone_skip;
-
-               /*
-                * Wrap from the beginning, if we exceed the file size
-                */
-               if (f->file_offset >= f->real_file_size)
-                       f->file_offset = f->real_file_size - f->file_offset;
-               f->last_pos[io_u->ddir] = f->file_offset;
-               td->io_skip_bytes += td->o.zone_skip;
+       if (td->o.zone_range) {
+               __fill_io_u_zone(td, io_u);
        }
 
        /*