From c75f1778b9bbaf5877529103ac803a965fe1973d Mon Sep 17 00:00:00 2001 From: Bar David Date: Thu, 1 Jul 2021 16:32:52 +0300 Subject: [PATCH] dedupe: fixing bug with subsequent dedupe buffer generation 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 --- fio.h | 1 + io_u.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/fio.h b/fio.h index b05cb3df..83334652 100644 --- 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 b421a579..b60488a3 100644 --- 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; } -- 2.25.1