Basic support for dedupe
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index 2adaf258d3912bc33599ca550079f9769c3f70e8..af3b415160609d9dbb5317ef27c4d67d004be23b 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -1532,15 +1532,12 @@ void io_u_log_error(struct thread_data *td, struct io_u *io_u)
        if (td_non_fatal_error(td, eb, io_u->error) && !td->o.error_dump)
                return;
 
-       log_err("fio: io_u error");
-
-       if (io_u->file)
-               log_err(" on file %s", io_u->file->file_name);
-
-       log_err(": %s\n", strerror(io_u->error));
-
-       log_err("     %s offset=%llu, buflen=%lu\n", io_ddir_name(io_u->ddir),
-                                       io_u->offset, io_u->xfer_buflen);
+       log_err("fio: io_u error%s%s: %s: %s offset=%llu, buflen=%lu\n",
+               io_u->file ? " on file " : "",
+               io_u->file ? io_u->file->file_name : "",
+               strerror(io_u->error),
+               io_ddir_name(io_u->ddir),
+               io_u->offset, io_u->xfer_buflen);
 
        if (!td->error)
                td_verror(td, io_u->error, "io_u error");
@@ -1831,6 +1828,32 @@ void io_u_queued(struct thread_data *td, struct io_u *io_u)
        }
 }
 
+/*
+ * See if we should reuse the last seed, if dedupe is enabled
+ */
+static struct frand_state *get_buf_state(struct thread_data *td)
+{
+       unsigned int v;
+       unsigned long r;
+
+       if (!td->o.dedupe_percentage)
+               return &td->buf_state;
+
+       r = __rand(&td->dedupe_state);
+       v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
+
+       if (v <= td->o.dedupe_percentage)
+               return &td->buf_state_prev;
+
+       return &td->buf_state;
+}
+
+static void save_buf_state(struct thread_data *td, struct frand_state *rs)
+{
+       if (rs == &td->buf_state)
+               frand_copy(&td->buf_state_prev, rs);
+}
+
 void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write,
                    unsigned int max_bs)
 {
@@ -1838,6 +1861,9 @@ void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write,
                fill_buffer_pattern(td, buf, max_bs);
        else if (!td->o.zero_buffers) {
                unsigned int perc = td->o.compress_percentage;
+               struct frand_state *rs;
+
+               rs = get_buf_state(td);
 
                if (perc) {
                        unsigned int seg = min_write;
@@ -1846,10 +1872,12 @@ void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write,
                        if (!seg)
                                seg = min_write;
 
-                       fill_random_buf_percentage(&td->buf_state, buf,
-                                               perc, seg, max_bs);
-               } else
-                       fill_random_buf(&td->buf_state, buf, max_bs);
+                       fill_random_buf_percentage(rs, buf, perc, seg,max_bs);
+                       save_buf_state(td, rs);
+               } else {
+                       fill_random_buf(rs, buf, max_bs);
+                       save_buf_state(td, rs);
+               }
        } else
                memset(buf, 0, max_bs);
 }