dedupe: fixing bug with subsequent dedupe buffer generation
authorBar David <Bar.David@dell.com>
Thu, 1 Jul 2021 13:32:52 +0000 (16:32 +0300)
committerBar David <bardavvid@gmail.com>
Thu, 1 Jul 2021 13:39:21 +0000 (16:39 +0300)
When unique pages are generated onto the write buffer the seed
used to generate the page is copied later to the buf_state_prev
for future dedupe generation.

However, the get_buf_state API returns pointer to the prev
seed. Then when the caller uses it to re-generate the buffer
it changes the internal seed and advances the PRNG.
A subsequent intention to create another dedup might result in
generating a unique page instead.

Signed-off-by: Bar David <bardavvid@gmail.com>
fio.h
io_u.c

diff --git a/fio.h b/fio.h
index b05cb3dfc395346fe02775e65d7a4fba5288ed43..83334652e61b79fb576ad972ee625f1d04512439 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -259,6 +259,7 @@ struct thread_data {
 
        struct frand_state buf_state;
        struct frand_state buf_state_prev;
+       struct frand_state buf_state_ret;
        struct frand_state dedupe_state;
        struct frand_state zone_state;
        struct frand_state prio_state;
diff --git a/io_u.c b/io_u.c
index b421a579bd0a1aaa594692a21731a2774de77cea..b60488a3020f53382907abc7653e7d927eac8d4c 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -2182,8 +2182,16 @@ static struct frand_state *get_buf_state(struct thread_data *td)
 
        v = rand_between(&td->dedupe_state, 1, 100);
 
-       if (v <= td->o.dedupe_percentage)
-               return &td->buf_state_prev;
+       if (v <= td->o.dedupe_percentage) {
+               /*
+                * The caller advances the returned frand_state.
+                * A copy of prev should be returned instead since
+                * a subsequent intention to generate a deduped buffer
+                * might result in generating a unique one
+                */
+               frand_copy(&td->buf_state_ret, &td->buf_state_prev);
+               return &td->buf_state_ret;
+       }
 
        return &td->buf_state;
 }