More iolog fixes
[fio.git] / log.c
diff --git a/log.c b/log.c
index d59c38fd4e7cee46aa8f199b7f570e8c93b23501..9669b4a7c336eb510a510679c7933d9e96c45bd1 100644 (file)
--- a/log.c
+++ b/log.c
@@ -19,6 +19,11 @@ int read_iolog_get(struct thread_data *td, struct io_u *io_u)
                io_u->buflen = ipo->len;
                io_u->ddir = ipo->ddir;
                io_u->file = ipo->file;
+               /*
+                * work around, this needs a format change to work for > 1 file
+                */
+               if (!io_u->file)
+                       io_u->file = &td->files[0];
                free(ipo);
                return 0;
        }
@@ -43,16 +48,34 @@ void prune_io_piece_log(struct thread_data *td)
  */
 void log_io_piece(struct thread_data *td, struct io_u *io_u)
 {
-       struct rb_node **p = &td->io_hist_tree.rb_node;
-       struct rb_node *parent = NULL;
+       struct rb_node **p, *parent;
        struct io_piece *ipo, *__ipo;
 
        ipo = malloc(sizeof(struct io_piece));
-       memset(&ipo->rb_node, 0, sizeof(ipo->rb_node));
        ipo->file = io_u->file;
        ipo->offset = io_u->offset;
        ipo->len = io_u->buflen;
 
+       /*
+        * We don't need to sort the entries, if:
+        *
+        *      Sequential writes, or
+        *      Random writes that lay out the file as it goes along
+        *
+        * For both these cases, just reading back data in the order we
+        * wrote it out is the fastest.
+        */
+       if (!td_random(td) || !td->o.overwrite ||
+            (io_u->file->flags & FIO_FILE_NOSORT)) {
+               INIT_LIST_HEAD(&ipo->list);
+               list_add_tail(&ipo->list, &td->io_hist_list);
+               return;
+       }
+
+       RB_CLEAR_NODE(&ipo->rb_node);
+       p = &td->io_hist_tree.rb_node;
+       parent = NULL;
+
        /*
         * Sort the entry into the verification list
         */
@@ -60,12 +83,10 @@ void log_io_piece(struct thread_data *td, struct io_u *io_u)
                parent = *p;
 
                __ipo = rb_entry(parent, struct io_piece, rb_node);
-               if (ipo->offset < __ipo->offset)
+               if (ipo->offset <= __ipo->offset)
                        p = &(*p)->rb_left;
-               else if (ipo->offset > __ipo->offset)
-                       p = &(*p)->rb_right;
                else
-                       break;
+                       p = &(*p)->rb_right;
        }
 
        rb_link_node(&ipo->rb_node, parent, p);
@@ -119,6 +140,7 @@ static int init_iolog_read(struct thread_data *td)
                }
 
                ipo = malloc(sizeof(*ipo));
+               memset(ipo, 0, sizeof(*ipo));
                INIT_LIST_HEAD(&ipo->list);
                ipo->offset = offset;
                ipo->len = bytes;
@@ -150,6 +172,11 @@ static int init_iolog_write(struct thread_data *td)
 {
        FILE *f;
 
+       if (td->o.nr_files > 1) {
+               log_err("fio: write_iolog only works with 1 file currently\n");
+               return 1;
+       }
+
        f = fopen(td->o.write_iolog_file, "w+");
        if (!f) {
                perror("fopen write iolog");