Fix access of freed memory
[fio.git] / log.c
diff --git a/log.c b/log.c
index ba52f0768744df5ea19cec1c2758a399e0cc8db9..6117b702c49e4fa345dad601362f65085362ee32 100644 (file)
--- a/log.c
+++ b/log.c
@@ -20,9 +20,10 @@ void queue_io_piece(struct thread_data *td, struct io_piece *ipo)
 
 void log_io_u(struct thread_data *td, struct io_u *io_u)
 {
-       const char *act[] = { "read", "write", "sync", "datasync" };
+       const char *act[] = { "read", "write", "sync", "datasync",
+                               "sync_file_range" };
 
-       assert(io_u->ddir < 3);
+       assert(io_u->ddir <= 4);
 
        if (!td->o.write_iolog_file)
                return;
@@ -130,10 +131,10 @@ int read_iolog_get(struct thread_data *td, struct io_u *io_u)
                        io_u->buflen = ipo->len;
                        io_u->file = td->files[ipo->fileno];
                        get_file(io_u->file);
-
                        dprint(FD_IO, "iolog: get %llu/%lu/%s\n", io_u->offset,
                                                io_u->buflen, io_u->file->file_name);
-                       if (ipo->delay) iolog_delay(td, ipo->delay);
+                       if (ipo->delay)
+                               iolog_delay(td, ipo->delay);
                } else {
                        elapsed = mtime_since_genesis();
                        if (ipo->delay > elapsed)
@@ -143,7 +144,7 @@ int read_iolog_get(struct thread_data *td, struct io_u *io_u)
 
                free(ipo);
                
-               if (ipo->ddir != DDIR_WAIT)
+               if (io_u->ddir != DDIR_WAIT)
                        return 0;
        }
 
@@ -159,12 +160,14 @@ void prune_io_piece_log(struct thread_data *td)
        while ((n = rb_first(&td->io_hist_tree)) != NULL) {
                ipo = rb_entry(n, struct io_piece, rb_node);
                rb_erase(n, &td->io_hist_tree);
+               td->io_hist_len--;
                free(ipo);
        }
 
        while (!flist_empty(&td->io_hist_list)) {
                ipo = flist_entry(td->io_hist_list.next, struct io_piece, list);
                flist_del(&ipo->list);
+               td->io_hist_len--;
                free(ipo);
        }
 }
@@ -200,6 +203,7 @@ void log_io_piece(struct thread_data *td, struct io_u *io_u)
              (file_randommap(td, ipo->file) || td->o.verify == VERIFY_NONE)) {
                INIT_FLIST_HEAD(&ipo->list);
                flist_add_tail(&ipo->list, &td->io_hist_list);
+               td->io_hist_len++;
                return;
        }
 
@@ -215,19 +219,26 @@ restart:
                parent = *p;
 
                __ipo = rb_entry(parent, struct io_piece, rb_node);
-               if (ipo->offset < __ipo->offset)
+               if (ipo->file < __ipo->file)
+                       p = &(*p)->rb_left;
+               else if (ipo->file > __ipo->file)
+                       p = &(*p)->rb_right;
+               else if (ipo->offset < __ipo->offset)
                        p = &(*p)->rb_left;
                else if (ipo->offset > __ipo->offset)
                        p = &(*p)->rb_right;
                else {
                        assert(ipo->len == __ipo->len);
+                       td->io_hist_len--;
                        rb_erase(parent, &td->io_hist_tree);
+                       free(__ipo);
                        goto restart;
                }
        }
 
        rb_link_node(&ipo->rb_node, parent, p);
        rb_insert_color(&ipo->rb_node, &td->io_hist_tree);
+       td->io_hist_len++;
 }
 
 void write_iolog_close(struct thread_data *td)