diff --git a/f3read.1 b/f3read.1 index 51830ba..e37508f 100644 --- a/f3read.1 +++ b/f3read.1 @@ -18,7 +18,7 @@ card and then checks if can read it. It will assure you haven't been sold a card with a smaller capacity than stated. .PP When writing to flash drive, \fBf3write\fP fills the filesystem with 1GB -files named N.fff, where N is a number (i.e. /[0-9]+/). +files named N.h2w, where N is a number (i.e. /[0-9]+/). .PP WARNING: all data on the tested disk might be lost! .SH OPTIONS diff --git a/f3read.c b/f3read.c index 27e6560..60771f0 100644 --- a/f3read.c +++ b/f3read.c @@ -44,8 +44,6 @@ static void validate_file(const char *path, int number, int offset_match, error_count; size_t sectors_read; uint64_t offset, expected_offset; - struct drand48_data state; - long int rand_int; int final_errno; struct timeval t1, t2; /* Progress time. */ @@ -79,17 +77,19 @@ static void validate_file(const char *path, int number, final_errno = errno; expected_offset = (uint64_t)number * GIGABYTES; while (sectors_read > 0) { + uint64_t rn; + assert(sectors_read == 1); offset = *((uint64_t *) sector); offset_match = offset == expected_offset; - srand48_r(offset, &state); + rn = offset; p = sector + sizeof(offset); error_count = 0; for (; error_count <= TOLERANCE && p < ptr_end; - p += sizeof(long int)) { - lrand48_r(&state, &rand_int); - if (rand_int != *((long int *) p)) + p += sizeof(rn)) { + rn = random_number(rn); + if (rn != *((typeof(rn) *) p)) error_count++; } diff --git a/f3write.c b/f3write.c index 4039577..0fc833b 100644 --- a/f3write.c +++ b/f3write.c @@ -18,20 +18,24 @@ static uint64_t fill_buffer(void *buf, size_t size, uint64_t offset) { uint8_t *p, *ptr_next_sector, *ptr_end; - struct drand48_data state; + uint64_t rn; assert(size > 0); assert(size % SECTOR_SIZE == 0); + assert(SECTOR_SIZE >= sizeof(offset) + sizeof(rn)); + assert((SECTOR_SIZE - sizeof(offset)) % sizeof(rn) == 0); p = buf; ptr_end = p + size; while (p < ptr_end) { + rn = offset; memmove(p, &offset, sizeof(offset)); - srand48_r(offset, &state); ptr_next_sector = p + SECTOR_SIZE; p += sizeof(offset); - for (; p < ptr_next_sector; p += sizeof(long int)) - lrand48_r(&state, (long int *)p); + for (; p < ptr_next_sector; p += sizeof(rn)) { + rn = random_number(rn); + memmove(p, &rn, sizeof(rn)); + } assert(p == ptr_next_sector); offset += SECTOR_SIZE; } diff --git a/utils.c b/utils.c index db22f68..b0a6e1d 100644 --- a/utils.c +++ b/utils.c @@ -33,14 +33,14 @@ int is_my_file(const char *filename) p++; } while (isdigit(*p)); - return (p[0] == '.') && (p[1] == 'f') && (p[2] == 'f') && - (p[3] == 'f') && (p[4] == '\0'); + return (p[0] == '.') && (p[1] == 'h') && (p[2] == '2') && + (p[3] == 'w') && (p[4] == '\0'); } void full_fn_from_number(char *full_fn, const char **filename, const char *path, int num) { - assert(snprintf(full_fn, PATH_MAX, "%s/%i.fff", path, num + 1) < + assert(snprintf(full_fn, PATH_MAX, "%s/%i.h2w", path, num + 1) < PATH_MAX); *filename = full_fn + strlen(path) + 1; } @@ -140,80 +140,3 @@ void print_header(FILE *f, char *name) "This is free software; see the source for copying conditions.\n" "\n", name); } - -#if defined(APPLE_MAC) || defined (CYGWIN) - -#include -#include - -int srand48_r(long int seedval, struct drand48_data *buffer) -{ - /* The standards say we only have 32 bits. */ - if (sizeof(long int) > 4) - seedval &= 0xffffffffl; - - buffer->__x[2] = seedval >> 16; - buffer->__x[1] = seedval & 0xffffl; - buffer->__x[0] = 0x330e; - - buffer->__a = 0x5deece66dull; - buffer->__c = 0xb; - buffer->__init = 1; - - return 0; -} - -static int __drand48_iterate(unsigned short int xsubi[3], - struct drand48_data *buffer) -{ - uint64_t X; - uint64_t result; - - /* Initialize buffer, if not yet done. */ - if (__builtin_expect(!buffer->__init, 0)) { - buffer->__a = 0x5deece66dull; - buffer->__c = 0xb; - buffer->__init = 1; - } - - /* Do the real work. We choose a data type which contains at least - 48 bits. Because we compute the modulus it does not care how - many bits really are computed. */ - - X = (uint64_t) xsubi[2] << 32 | (uint32_t) xsubi[1] << 16 | xsubi[0]; - - result = X * buffer->__a + buffer->__c; - - xsubi[0] = result & 0xffff; - xsubi[1] = (result >> 16) & 0xffff; - xsubi[2] = (result >> 32) & 0xffff; - - return 0; -} - -static int __nrand48_r(unsigned short int xsubi[3], - struct drand48_data *buffer, long int *result) -{ - /* Compute next state. */ - if (__drand48_iterate(xsubi, buffer) < 0) - return -1; - - /* Store the result. */ - if (sizeof(unsigned short int) == 2) - *result = xsubi[2] << 15 | xsubi[1] >> 1; - else - *result = xsubi[2] >> 1; - - return 0; -} - -int lrand48_r(struct drand48_data *buffer, long int *result) -{ - /* Be generous for the arguments, detect some errors. */ - if (buffer == NULL) - return -1; - - return __nrand48_r(buffer->__x, buffer, result); -} - -#endif /* APPLE_MAC or CYGWIN */ diff --git a/utils.h b/utils.h index 771e384..e0fbaab 100644 --- a/utils.h +++ b/utils.h @@ -6,13 +6,14 @@ #include #include #include +#include #define SECTOR_SIZE (512) #define GIGABYTES (1024 * 1024 * 1024) const char *adjust_unit(double *ptr_bytes); -/* Return true if @filename matches the regex /^[0-9]+\.fff$/ */ +/* Return true if @filename matches the regex /^[0-9]+\.h2w$/ */ int is_my_file(const char *filename); /* @filename should be PATH_MAX long. */ @@ -35,6 +36,11 @@ const int *ls_my_files(const char *path, int start_at); void print_header(FILE *f, char *name); +static inline uint64_t random_number(uint64_t prv_number) +{ + return prv_number * 4294967311ULL + 17; +} + #ifdef APPLE_MAC /* For function fcntl. */ @@ -66,33 +72,4 @@ static inline int posix_fadvise(int fd, off_t offset, off_t len, int advice) #endif /* APPLE_MAC */ -#if defined(APPLE_MAC) || defined(CYGWIN) - -/* - * The following functions were copied from GNU Library C to make F3 - * more portable. - */ - -/* Data structure for communication with thread safe versions. This - * type is to be regarded as opaque. It's only exported because users - * have to allocate objects of this type. - */ -struct drand48_data { - unsigned short int __x[3]; /* Current state. */ - unsigned short int __old_x[3]; /* Old state. */ - unsigned short int __c; /* Additive const. in congruential formula. */ - unsigned short int __init; /* Flag for initializing. */ - unsigned long long int __a; /* Factor in congruential formula. */ -}; - -/* Seed random number generator. */ -extern int srand48_r(long int __seedval, struct drand48_data *__buffer) - __attribute__ ((nonnull(2))); - -/* Return non-negative, long integer in [0,2^31). */ -extern int lrand48_r(struct drand48_data *__restrict __buffer, - long int *__restrict __result) __attribute__ ((nonnull(1, 2))); - -#endif /* APPLE_MAC or CYGWIN */ - #endif /* HEADER_UTILS_H */