INIT_LIST_HEAD(&td->io_u_busylist);
INIT_LIST_HEAD(&td->io_u_requeues);
INIT_LIST_HEAD(&td->io_log_list);
+ INIT_LIST_HEAD(&td->io_hist_list);
td->io_hist_tree = RB_ROOT;
if (init_io_u(td))
unsigned int ddir_nr;
/*
- * IO historic logs
+ * IO history logs for verification. We use a tree for sorting,
+ * if we are overwriting. Otherwise just use a fifo.
*/
struct rb_root io_hist_tree;
+ struct list_head io_hist_list;
+
+ /*
+ * For IO replaying
+ */
struct list_head io_log_list;
/*
*/
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));
- RB_CLEAR_NODE(&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) {
+ 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
*/
int get_next_verify(struct thread_data *td, struct io_u *io_u)
{
- struct io_piece *ipo;
- struct rb_node *n;
+ struct io_piece *ipo = NULL;
/*
* this io_u is from a requeue, we already filled the offsets
if (io_u->file)
return 0;
- n = rb_first(&td->io_hist_tree);
- if (n) {
- ipo = rb_entry(n, struct io_piece, rb_node);
+ if (!RB_EMPTY_ROOT(&td->io_hist_tree)) {
+ struct rb_node *n = rb_first(&td->io_hist_tree);
+ ipo = rb_entry(n, struct io_piece, rb_node);
rb_erase(n, &td->io_hist_tree);
+ } else if (!list_empty(&td->io_hist_list)) {
+ ipo = list_entry(td->io_hist_list.next, struct io_piece, list);
+ list_del(&ipo->list);
+ }
+ if (ipo) {
io_u->offset = ipo->offset;
io_u->buflen = ipo->len;
io_u->file = ipo->file;