verify: add new experimental mode that requires no meta data
[fio.git] / lib / lfsr.c
index 64442ab536d40fc2ac3894fc30043fcc94ef1e2b..61a3aaf3e6532c32722314da125bcce69cf98416 100644 (file)
@@ -3,7 +3,7 @@
 #include "lfsr.h"
 
 /*
- * Trom table 3 of
+ * From table 3 of
  *
  * http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
  */
@@ -202,6 +202,8 @@ static struct lfsr_taps lfsr_taps[] = {
        },
 };
 
+#define FIO_LFSR_CRANKS                128
+
 static uint64_t __lfsr_next(uint64_t v, struct lfsr_taps *lt)
 {
        uint64_t xor_mask = 0;
@@ -214,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);
 
@@ -235,13 +238,24 @@ static struct lfsr_taps *find_lfsr(uint64_t size)
        int i;
 
        for (i = 0; lfsr_taps[i].length; i++)
-               if ((1UL << lfsr_taps[i].length) >= size)
+               if (((1UL << lfsr_taps[i].length) + FIO_LFSR_CRANKS) >= size)
                        return &lfsr_taps[i];
 
        return NULL;
 }
 
-int lfsr_init(struct fio_lfsr *fl, uint64_t size)
+void lfsr_reset(struct fio_lfsr *fl, unsigned long seed)
+{
+       unsigned int i;
+
+       fl->last_val = seed;
+       fl->num_vals = 0;
+
+       for (i = 0; i < FIO_LFSR_CRANKS; i++)
+               fl->last_val = __lfsr_next(fl->last_val, &fl->taps);
+}
+
+int lfsr_init(struct fio_lfsr *fl, uint64_t size, unsigned long seed)
 {
        struct lfsr_taps *tap;
        int i;
@@ -250,15 +264,15 @@ int lfsr_init(struct fio_lfsr *fl, uint64_t size)
        if (!tap)
                return 1;
 
-       fl->last_val = 1;
        fl->max_val = size - 1;
-       fl->num_vals = 0;
        fl->taps.length = tap->length;
+
        for (i = 0; i < FIO_MAX_TAPS; i++) {
                fl->taps.taps[i] = tap->taps[i];
                if (!fl->taps.taps[i])
                        break;
        }
 
+       lfsr_reset(fl, seed);
        return 0;
 }