From: Jens Axboe Date: Fri, 11 Jan 2013 13:03:25 +0000 (+0100) Subject: lfsr: ensure we don't generate an offset + buflen that exceeds the max size X-Git-Tag: fio-2.0.14~128 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=7477673323a943b99ea203bb9434661d13a0159c;hp=38f30c81d8d194da047950cbbda3896bd35cd98c lfsr: ensure we don't generate an offset + buflen that exceeds the max size Currently we check for the max value, but that doesn't always work since it may not fit the minimum block size (even if it is guaranteed to be smaller than the max offset). Pass in the last valid block. Signed-off-by: Jens Axboe --- diff --git a/io_u.c b/io_u.c index 91d1290f..94fd1234 100644 --- a/io_u.c +++ b/io_u.c @@ -49,11 +49,11 @@ static void mark_random_map(struct thread_data *td, struct io_u *io_u) io_u->buflen = nr_blocks * min_bs; } -static unsigned long long last_block(struct thread_data *td, struct fio_file *f, - enum fio_ddir ddir) +static uint64_t last_block(struct thread_data *td, struct fio_file *f, + enum fio_ddir ddir) { - unsigned long long max_blocks; - unsigned long long max_size; + uint64_t max_blocks; + uint64_t max_size; assert(ddir_rw(ddir)); @@ -77,14 +77,14 @@ static unsigned long long last_block(struct thread_data *td, struct fio_file *f, static int __get_next_rand_offset(struct thread_data *td, struct fio_file *f, enum fio_ddir ddir, unsigned long long *b) { - unsigned long long r; + unsigned long long r, lastb; - if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE) { - unsigned long long rmax, lastb; + lastb = last_block(td, f, ddir); + if (!lastb) + return 1; - lastb = last_block(td, f, ddir); - if (!lastb) - return 1; + if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE) { + unsigned long long rmax; rmax = td->o.use_os_rand ? OS_RAND_MAX : FRAND_MAX; @@ -102,7 +102,7 @@ static int __get_next_rand_offset(struct thread_data *td, struct fio_file *f, } else { uint64_t off = 0; - if (lfsr_next(&f->lfsr, &off)) + if (lfsr_next(&f->lfsr, &off, lastb)) return 1; *b = off; diff --git a/lib/lfsr.c b/lib/lfsr.c index 8a700296..975c6a5a 100644 --- a/lib/lfsr.c +++ b/lib/lfsr.c @@ -216,14 +216,15 @@ static uint64_t __lfsr_next(uint64_t v, struct lfsr_taps *lt) return xor_mask | (v >> 1); } -int lfsr_next(struct fio_lfsr *fl, uint64_t *off) +int lfsr_next(struct fio_lfsr *fl, uint64_t *off, uint64_t last) { if (fl->num_vals > fl->max_val) return 1; do { fl->last_val = __lfsr_next(fl->last_val, &fl->taps); - if (fl->last_val - 1 <= fl->max_val) + if (fl->last_val - 1 <= fl->max_val && + fl->last_val <= last) break; } while (1); diff --git a/lib/lfsr.h b/lib/lfsr.h index 09f5ac0b..898646e2 100644 --- a/lib/lfsr.h +++ b/lib/lfsr.h @@ -18,7 +18,7 @@ struct fio_lfsr { struct lfsr_taps taps; }; -int lfsr_next(struct fio_lfsr *fl, uint64_t *off); +int lfsr_next(struct fio_lfsr *fl, uint64_t *off, uint64_t); int lfsr_init(struct fio_lfsr *fl, uint64_t size, unsigned long seed); #endif