Reviewed code

This commit is contained in:
Michel Machado 2011-12-20 13:36:29 -05:00
parent 0510a6c08d
commit cbadb0c91c
4 changed files with 48 additions and 30 deletions

View File

@ -4,7 +4,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <dirent.h> #include <dirent.h>
#include <stdio.h> #include <stdio.h>
#include <ctype.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
@ -28,6 +27,17 @@ static uint64_t offset_from_filename(const char *filename)
return number * GIGABYTES; return number * GIGABYTES;
} }
static inline void update_dt(struct timeval *dt, const struct timeval *t1,
const struct timeval *t2)
{
dt->tv_sec += t2->tv_sec - t1->tv_sec;
dt->tv_usec += t2->tv_usec - t1->tv_usec;
if (dt->tv_usec >= 1000000) {
dt->tv_sec++;
dt->tv_usec -= 1000000;
}
}
#define TOLERANCE 2 #define TOLERANCE 2
#define PRINT_STATUS(s) printf("%s%7" PRIu64 "/%9" PRIu64 "/%7" PRIu64 "/%7" \ #define PRINT_STATUS(s) printf("%s%7" PRIu64 "/%9" PRIu64 "/%7" PRIu64 "/%7" \
@ -57,8 +67,7 @@ static void validate_file(const char *path, const char *filename,
/* Progress time. */ /* Progress time. */
struct timeval pt1 = { .tv_sec = -1000, .tv_usec = 0 }; struct timeval pt1 = { .tv_sec = -1000, .tv_usec = 0 };
*ptr_ok = *ptr_corrupted = *ptr_changed = *ptr_overwritten = *ptr_ok = *ptr_corrupted = *ptr_changed = *ptr_overwritten = 0;
*ptr_size = 0;
printf("Validating file %s ... %s", filename, progress ? BLANK : ""); printf("Validating file %s ... %s", filename, progress ? BLANK : "");
fflush(stdout); fflush(stdout);
@ -130,7 +139,8 @@ static void validate_file(const char *path, const char *filename,
*read_all = feof(f); *read_all = feof(f);
assert(*read_all || errno == EIO); assert(*read_all || errno == EIO);
*ptr_size += ftell(f); *ptr_size = ftell(f);
assert(*ptr_size >= 0);
fclose(f); fclose(f);
tail_msg = read_all ? "" : " - NOT fully read"; tail_msg = read_all ? "" : " - NOT fully read";
@ -145,6 +155,13 @@ static void report(const char *prefix, uint64_t i)
printf("%s %.2f %s (%" PRIu64 " sectors)\n", prefix, f, unit, i); printf("%s %.2f %s (%" PRIu64 " sectors)\n", prefix, f, unit, i);
} }
static inline double dt_to_s(struct timeval *dt)
{
double ret = (double)dt->tv_sec + ((double)dt->tv_usec / 1000000.);
assert(ret >= 0);
return ret > 0 ? ret : 1;
}
static int iterate_path(const char *path, int progress) static int iterate_path(const char *path, int progress)
{ {
DIR *ptr_dir; DIR *ptr_dir;

View File

@ -22,7 +22,7 @@ static uint64_t fill_buffer(void *buf, size_t size, uint64_t offset)
uint8_t *p, *ptr_next_sector, *ptr_end; uint8_t *p, *ptr_next_sector, *ptr_end;
struct drand48_data state; struct drand48_data state;
/* Assumed that size is not zero and a sector-size multiple. */ assert(size > 0);
assert(size % SECTOR_SIZE == 0); assert(size % SECTOR_SIZE == 0);
p = buf; p = buf;
@ -48,7 +48,7 @@ struct flow {
uint64_t total_written; uint64_t total_written;
/* If true, show progress. */ /* If true, show progress. */
int progress; int progress;
/* Writing rate. */ /* Writing rate in bytes. */
int block_size; int block_size;
/* Blocks to write before measurement. */ /* Blocks to write before measurement. */
int blocks_per_delay; int blocks_per_delay;
@ -87,6 +87,7 @@ static inline void init_flow(struct flow *fw, uint64_t total_size, int progress)
fw->measured_blocks = 0; fw->measured_blocks = 0;
fw->state = FW_START; fw->state = FW_START;
fw->erase = 0; fw->erase = 0;
assert(fw->block_size > 0);
assert(fw->block_size % SECTOR_SIZE == 0); assert(fw->block_size % SECTOR_SIZE == 0);
} }
@ -113,6 +114,7 @@ static void erase(int count)
repeat_ch('\b', count); repeat_ch('\b', count);
} }
/* Average writing speed in byte/s. */
static inline double get_avg_speed(struct flow *fw) static inline double get_avg_speed(struct flow *fw)
{ {
return (double)(fw->measured_blocks * fw->block_size * 1000) / return (double)(fw->measured_blocks * fw->block_size * 1000) /
@ -178,7 +180,15 @@ static void measure(int fd, struct flow *fw)
fw->bpd1 = fw->blocks_per_delay / 2; fw->bpd1 = fw->blocks_per_delay / 2;
fw->bpd2 = fw->blocks_per_delay; fw->bpd2 = fw->blocks_per_delay;
fw->blocks_per_delay = (fw->bpd1 + fw->bpd2) / 2; fw->blocks_per_delay = (fw->bpd1 + fw->bpd2) / 2;
assert(fw->bpd1 > 0); assert(fw->bpd1 >= 0);
/* The following should be true only when the kernel
* is already too busy with the device.
*/
if (fw->bpd1 == 0) {
fw->bpd1++;
fw->bpd2++;
fw->blocks_per_delay++;
}
fw->state = FW_SEARCH; fw->state = FW_SEARCH;
} else if (delay < fw->delay_ms) { } else if (delay < fw->delay_ms) {
fw->blocks_per_delay *= 2; fw->blocks_per_delay *= 2;
@ -318,7 +328,7 @@ static int create_and_fill_file(const char *path, int number, size_t size,
static inline uint64_t get_freespace(const char *path) static inline uint64_t get_freespace(const char *path)
{ {
struct statvfs fs; struct statvfs fs;
assert(statvfs(path, &fs) == 0); assert(!statvfs(path, &fs));
return (uint64_t)fs.f_frsize * (uint64_t)fs.f_bfree; return (uint64_t)fs.f_frsize * (uint64_t)fs.f_bfree;
} }
@ -342,6 +352,15 @@ static int fill_fs(const char *path, int progress)
return 1; return 1;
} }
/* This sync is just to minimize the chance we'll misestimate
* the writting speed, especially at beginning that can slow down
* the whole process.
* This issue was spotted on a large pen drive in which all fff files
* were removed by function unlink_old_files, but the metadata
* wasn't properly flushed before reaching here.
*/
sync();
init_flow(&fw, free_space, progress); init_flow(&fw, free_space, progress);
i = 0; i = 0;
fine = 1; fine = 1;

View File

@ -2,11 +2,11 @@
const char *adjust_unit(double *ptr_bytes) const char *adjust_unit(double *ptr_bytes)
{ {
char *units[] = { "Byte", "KB", "MB", "GB", "TB" }; const char *units[] = { "Byte", "KB", "MB", "GB", "TB", "PB", "EB" };
int i = 0; int i = 0;
double final = *ptr_bytes; double final = *ptr_bytes;
while (i < 5 && final >= 1024) { while (i < 7 && final >= 1024) {
final /= 1024; final /= 1024;
i++; i++;
} }
@ -14,7 +14,7 @@ const char *adjust_unit(double *ptr_bytes)
return units[i]; return units[i];
} }
#ifndef APPLE_MAC #ifdef APPLE_MAC
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>

18
utils.h
View File

@ -27,24 +27,6 @@ static inline void get_full_fn(char *full_fn, int len,
assert(snprintf(full_fn, len, "%s/%s", path, filename) < len); assert(snprintf(full_fn, len, "%s/%s", path, filename) < len);
} }
static inline void update_dt(struct timeval *dt, const struct timeval *t1,
const struct timeval *t2)
{
dt->tv_sec += t2->tv_sec - t1->tv_sec;
dt->tv_usec += t2->tv_usec - t1->tv_usec;
if (dt->tv_usec >= 1000000) {
dt->tv_sec++;
dt->tv_usec -= 1000000;
}
}
static inline double dt_to_s(struct timeval *dt)
{
double ret = (double)dt->tv_sec + ((double)dt->tv_usec / 1000000.);
assert(ret >= 0.);
return ret > 0. ? ret : 1.;
}
static inline long delay_ms(const struct timeval *t1, const struct timeval *t2) static inline long delay_ms(const struct timeval *t1, const struct timeval *t2)
{ {
return (t2->tv_sec - t1->tv_sec) * 1000 + return (t2->tv_sec - t1->tv_sec) * 1000 +