lfsr: ensure we don't generate an offset + buflen that exceeds the max size
authorJens Axboe <axboe@kernel.dk>
Fri, 11 Jan 2013 13:03:25 +0000 (14:03 +0100)
committerJens Axboe <axboe@kernel.dk>
Fri, 11 Jan 2013 13:03:25 +0000 (14:03 +0100)
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 <axboe@kernel.dk>
io_u.c
lib/lfsr.c
lib/lfsr.h

diff --git a/io_u.c b/io_u.c
index 91d1290..94fd123 100644 (file)
--- 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;
index 8a70029..975c6a5 100644 (file)
@@ -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);
 
index 09f5ac0..898646e 100644 (file)
@@ -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