-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Open
Labels
Description
Some functions use unsigned long to store the rand_seed, which leads to value truncation when using LLP64 compilers:
- The random buffer is not fully initialized. The upper 32-bit is zeroed.
- The
rand_seedin the state header is also truncated. fio cannot verify it when--rw=readwrite.
For example, the following command doesn't work on Windows:$ fio --filename=test.bin --name=test --size=1m --rw=rw --verify=md5
I also have doubt on the following if-statement: Should it be AND or OR?
int verify_io_u(struct thread_data *td, struct io_u **io_u_ptr)
{
....
/*
* Make rand_seed check pass when have verify_backlog.
*/
if (!td_rw(td) || (td->flags & TD_F_VER_BACKLOG))
io_u->rand_seed = hdr->rand_seed;
If there's no requirement on backward compatibility, then we should replace the data type by unsigned long long. Here's my patch for review:
diff --git a/lib/rand.c b/lib/rand.c
index f18bd8d8..c166d3a6 100644
--- a/lib/rand.c
+++ b/lib/rand.c
@@ -95,7 +95,7 @@ void init_rand_seed(struct frand_state *state, unsigned int seed, bool use64)
__init_rand64(&state->state64, seed);
}
-void __fill_random_buf(void *buf, unsigned int len, unsigned long seed)
+void __fill_random_buf(void *buf, unsigned int len, unsigned long long seed)
{
void *ptr = buf;
@@ -122,10 +122,10 @@ void __fill_random_buf(void *buf, unsigned int len, unsigned long seed)
}
}
-unsigned long fill_random_buf(struct frand_state *fs, void *buf,
+unsigned long long fill_random_buf(struct frand_state *fs, void *buf,
unsigned int len)
{
- unsigned long r = __rand(fs);
+ unsigned long long r = __rand(fs);
if (sizeof(int) != sizeof(long *))
r *= (unsigned long) __rand(fs);
@@ -134,7 +134,7 @@ unsigned long fill_random_buf(struct frand_state *fs, void *buf,
return r;
}
-void __fill_random_buf_percentage(unsigned long seed, void *buf,
+void __fill_random_buf_percentage(unsigned long long seed, void *buf,
unsigned int percentage,
unsigned int segment, unsigned int len,
char *pattern, unsigned int pbytes)
@@ -183,12 +183,12 @@ void __fill_random_buf_percentage(unsigned long seed, void *buf,
}
}
-unsigned long fill_random_buf_percentage(struct frand_state *fs, void *buf,
+unsigned long long fill_random_buf_percentage(struct frand_state *fs, void *buf,
unsigned int percentage,
unsigned int segment, unsigned int len,
char *pattern, unsigned int pbytes)
{
- unsigned long r = __rand(fs);
+ unsigned long long r = __rand(fs);
if (sizeof(int) != sizeof(long *))
r *= (unsigned long) __rand(fs);
diff --git a/lib/rand.h b/lib/rand.h
index 1676cf98..117d8974 100644
--- a/lib/rand.h
+++ b/lib/rand.h
@@ -150,9 +150,9 @@ static inline uint64_t rand_between(struct frand_state *state, uint64_t start,
extern void init_rand(struct frand_state *, bool);
extern void init_rand_seed(struct frand_state *, unsigned int seed, bool);
-extern void __fill_random_buf(void *buf, unsigned int len, unsigned long seed);
-extern unsigned long fill_random_buf(struct frand_state *, void *buf, unsigned int len);
-extern void __fill_random_buf_percentage(unsigned long, void *, unsigned int, unsigned int, unsigned int, char *, unsigned int);
-extern unsigned long fill_random_buf_percentage(struct frand_state *, void *, unsigned int, unsigned int, unsigned int, char *, unsigned int);
+extern void __fill_random_buf(void *buf, unsigned int len, unsigned long long seed);
+extern unsigned long long fill_random_buf(struct frand_state *, void *buf, unsigned int len);
+extern void __fill_random_buf_percentage(unsigned long long, void *, unsigned int, unsigned int, unsigned int, char *, unsigned int);
+extern unsigned long long fill_random_buf_percentage(struct frand_state *, void *, unsigned int, unsigned int, unsigned int, char *, unsigned int);
#endif
diff --git a/verify.c b/verify.c
index da429e79..7d01a611 100644
--- a/verify.c
+++ b/verify.c
@@ -45,7 +45,7 @@ static void __fill_buffer(struct thread_options *o, unsigned long seed, void *p,
__fill_random_buf_percentage(seed, p, o->compress_percentage, len, len, o->buffer_pattern, o->buffer_pattern_bytes);
}
-static unsigned long fill_buffer(struct thread_data *td, void *p,
+static unsigned long long fill_buffer(struct thread_data *td, void *p,
unsigned int len)
{
struct frand_state *fs = &td->verify_state;