dedupe: fix dedupe_percentage=100
authorJens Axboe <axboe@fb.com>
Mon, 27 Apr 2015 14:38:33 +0000 (08:38 -0600)
committerJens Axboe <axboe@fb.com>
Mon, 27 Apr 2015 14:38:33 +0000 (08:38 -0600)
The corner case of 100% dedupable was buggy, save and restore random
state appropriate for that too.

Signed-off-by: Jens Axboe <axboe@fb.com>
io_u.c

diff --git a/io_u.c b/io_u.c
index 50644850463f3e212381ff552f88ce056b5d83b9..69ca6fe06ff8abfa30be5694a24bbca810c3e5f8 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -1889,15 +1889,18 @@ 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)
+static struct frand_state *get_buf_state(struct thread_data *td,
+                                        struct frand_state *save)
 {
        unsigned int v;
        unsigned long r;
 
        if (!td->o.dedupe_percentage)
                return &td->buf_state;
-       else if (td->o.dedupe_percentage == 100)
+       else if (td->o.dedupe_percentage == 100) {
+               frand_copy(save, &td->buf_state_prev);
                return &td->buf_state_prev;
+       }
 
        r = __rand(&td->dedupe_state);
        v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
@@ -1908,16 +1911,20 @@ static struct frand_state *get_buf_state(struct thread_data *td)
        return &td->buf_state;
 }
 
-static void save_buf_state(struct thread_data *td, struct frand_state *rs)
+static void save_buf_state(struct thread_data *td, struct frand_state *rs,
+                          struct frand_state *save)
 {
        if (rs == &td->buf_state)
                frand_copy(&td->buf_state_prev, rs);
+       else if (rs == &td->buf_state_prev && td->o.dedupe_percentage == 100)
+               frand_copy(rs, save);
 }
 
 void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write,
                    unsigned int max_bs)
 {
        struct thread_options *o = &td->o;
+       struct frand_state save = { 0, };
 
        if (o->compress_percentage || o->dedupe_percentage) {
                unsigned int perc = td->o.compress_percentage;
@@ -1925,7 +1932,7 @@ void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write,
                unsigned int left = max_bs;
 
                do {
-                       rs = get_buf_state(td);
+                       rs = get_buf_state(td, &save);
 
                        min_write = min(min_write, left);
 
@@ -1944,14 +1951,14 @@ void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write,
 
                        buf += min_write;
                        left -= min_write;
-                       save_buf_state(td, rs);
+                       save_buf_state(td, rs, &save);
                } while (left);
        } else if (o->buffer_pattern_bytes)
                fill_buffer_pattern(td, buf, max_bs);
        else if (o->zero_buffers)
                memset(buf, 0, max_bs);
        else
-               fill_random_buf(get_buf_state(td), buf, max_bs);
+               fill_random_buf(get_buf_state(td, NULL), buf, max_bs);
 }
 
 /*