Scramble default write buffer contents slightly
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index 51da223d3e02ab194c45a77e6249870d9d0a62d4..af2d05f360eaed2f4d6c169f6ee5eb5f62da18f8 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -249,7 +249,16 @@ static int get_next_seq_block(struct thread_data *td, struct fio_file *f,
        assert(ddir_rw(ddir));
 
        if (f->last_pos < f->real_file_size) {
-               *b = (f->last_pos - f->file_offset) / td->o.min_bs[ddir];
+               unsigned long long pos;
+
+               if (f->last_pos == f->file_offset && td->o.ddir_seq_add < 0)
+                       f->last_pos = f->real_file_size;
+
+               pos = f->last_pos - f->file_offset;
+               if (pos)
+                       pos += td->o.ddir_seq_add;
+
+               *b = pos / td->o.min_bs[ddir];
                return 0;
        }
 
@@ -481,6 +490,16 @@ static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir)
        } else
                usec = td->rate_pending_usleep[ddir];
 
+       /*
+        * We are going to sleep, ensure that we flush anything pending as
+        * not to skew our latency numbers
+        */
+       if (td->cur_depth) {
+               int fio_unused ret;
+
+               ret = io_u_queued_complete(td, td->cur_depth, NULL);
+       }
+
        fio_gettime(&t, NULL);
        usec_sleep(td, usec);
        usec = utime_since_now(&t);
@@ -1101,6 +1120,19 @@ static int check_get_verify(struct thread_data *td, struct io_u *io_u)
        return 0;
 }
 
+/*
+ * Fill offset and start time into the buffer content, to prevent too
+ * easy compressible data for simple de-dupe attempts.
+ */
+static void small_content_scramble(struct io_u *io_u)
+{
+       void *end;
+
+       *((unsigned long long *) io_u->xfer_buf) = io_u->offset;
+       end = io_u->xfer_buf + io_u->xfer_buflen - sizeof(io_u->start_time);
+       memcpy(end, &io_u->start_time, sizeof(io_u->start_time));
+}
+
 /*
  * Return an io_u to be processed. Gets a buflen and offset, sets direction,
  * etc. The returned io_u is fully ready to be prepped and submitted.
@@ -1109,6 +1141,7 @@ struct io_u *get_io_u(struct thread_data *td)
 {
        struct fio_file *f;
        struct io_u *io_u;
+       int do_scramble = 0;
 
        io_u = __get_io_u(td);
        if (!io_u) {
@@ -1154,6 +1187,8 @@ struct io_u *get_io_u(struct thread_data *td)
                        populate_verify_io_u(td, io_u);
                else if (td->o.refill_buffers && io_u->ddir == DDIR_WRITE)
                        io_u_fill_buffer(td, io_u, io_u->xfer_buflen);
+               else if (io_u->ddir == DDIR_WRITE)
+                       do_scramble = 1;
                else if (io_u->ddir == DDIR_READ) {
                        /*
                         * Reset the buf_filled parameters so next time if the
@@ -1174,6 +1209,8 @@ out:
        if (!td_io_prep(td, io_u)) {
                if (!td->o.disable_slat)
                        fio_gettime(&io_u->start_time, NULL);
+               if (do_scramble)
+                       small_content_scramble(io_u);
                return io_u;
        }
 err_put:
@@ -1431,7 +1468,7 @@ void io_u_fill_buffer(struct thread_data *td, struct io_u *io_u,
        io_u->buf_filled_len = 0;
 
        if (!td->o.zero_buffers)
-               fill_random_buf(io_u->buf, max_bs);
+               fill_random_buf(&td->buf_state, io_u->buf, max_bs);
        else
                memset(io_u->buf, 0, max_bs);
 }