mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 10:51:54 -04:00
Fix integer overflow when computing the progress percentage
This commit is contained in:
parent
a3270063dd
commit
85ca997bf2
4 changed files with 40 additions and 24 deletions
|
|
@ -4245,7 +4245,7 @@ void state_progress_end(struct snapraid_state* state, block_off_t countpos, bloc
|
|||
|
||||
elapsed = now - state->progress_whole_start - state->progress_wasted;
|
||||
|
||||
msg_bar("%u%% completed, %u MB accessed", countpos * 100 / countmax, countsize_MB);
|
||||
msg_bar("%u%% completed, %u MB accessed", muldiv(countpos, 100, countmax), countsize_MB);
|
||||
|
||||
msg_bar(" in %u:%02u", (unsigned)(elapsed / 3600), (unsigned)((elapsed % 3600) / 60));
|
||||
|
||||
|
|
@ -4405,7 +4405,7 @@ static void state_progress_graph(struct snapraid_state* state, struct snapraid_i
|
|||
struct snapraid_disk* disk = i->data;
|
||||
v = disk->progress_tick[current] - ref(disk->progress_tick, oldest);
|
||||
printr(disk->name, pad);
|
||||
printf("%3" PRIu64 "%% | ", v * 100 / tick_total);
|
||||
printf("%3u%% | ", muldiv(v, 100, tick_total));
|
||||
printc('*', v * bar / tick_total);
|
||||
printf("\n");
|
||||
|
||||
|
|
@ -4416,32 +4416,32 @@ static void state_progress_graph(struct snapraid_state* state, struct snapraid_i
|
|||
for (l = 0; l < state->level; ++l) {
|
||||
v = state->parity[l].progress_tick[current] - ref(state->parity[l].progress_tick, oldest);
|
||||
printr(lev_config_name(l), pad);
|
||||
printf("%3" PRIu64 "%% | ", v * 100 / tick_total);
|
||||
printf("%3u%% | ", muldiv(v, 100, tick_total));
|
||||
printc('*', v * bar / tick_total);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
v = state->progress_tick_raid[current] - ref(state->progress_tick_raid, oldest);
|
||||
printr("raid", pad);
|
||||
printf("%3" PRIu64 "%% | ", v * 100 / tick_total);
|
||||
printf("%3u%% | ", muldiv(v, 100, tick_total));
|
||||
printc('*', v * bar / tick_total);
|
||||
printf("\n");
|
||||
|
||||
v = state->progress_tick_hash[current] - ref(state->progress_tick_hash, oldest);
|
||||
printr("hash", pad);
|
||||
printf("%3" PRIu64 "%% | ", v * 100 / tick_total);
|
||||
printf("%3u%% | ", muldiv(v, 100, tick_total));
|
||||
printc('*', v * bar / tick_total);
|
||||
printf("\n");
|
||||
|
||||
v = state->progress_tick_sched[current] - ref(state->progress_tick_sched, oldest);
|
||||
printr("sched", pad);
|
||||
printf("%3" PRIu64 "%% | ", v * 100 / tick_total);
|
||||
printf("%3u%% | ", muldiv(v, 100, tick_total));
|
||||
printc('*', v * bar / tick_total);
|
||||
printf("\n");
|
||||
|
||||
v = state->progress_tick_misc[current] - ref(state->progress_tick_misc, oldest);
|
||||
printr("misc", pad);
|
||||
printf("%3" PRIu64 "%% | ", v * 100 / tick_total);
|
||||
printf("%3u%% | ", muldiv(v, 100, tick_total));
|
||||
printc('*', v * bar / tick_total);
|
||||
printf("\n");
|
||||
|
||||
|
|
@ -4499,7 +4499,7 @@ int state_progress(struct snapraid_state* state, struct snapraid_io* io, block_o
|
|||
|
||||
/* completion percentage */
|
||||
if (countmax)
|
||||
out_perc = countpos * 100 / countmax;
|
||||
out_perc = muldiv(countpos, 100, countmax);
|
||||
|
||||
/* if we have at least 5 measures */
|
||||
if (state->progress_tick >= 5
|
||||
|
|
@ -4565,11 +4565,11 @@ int state_progress(struct snapraid_state* state, struct snapraid_io* io, block_o
|
|||
|
||||
/* estimate the cpu usage percentage */
|
||||
if (delta_tick_total != 0)
|
||||
out_cpu = (unsigned)(delta_tick_cpu * 100U / delta_tick_total);
|
||||
out_cpu = muldiv(delta_tick_cpu, 100, delta_tick_total);
|
||||
|
||||
/* estimate the remaining time in minutes */
|
||||
if (delta_pos != 0)
|
||||
out_eta = (countmax - countpos) * delta_time / (60 * delta_pos);
|
||||
out_eta = muldiv(countmax - countpos, delta_time, 60 * delta_pos);
|
||||
|
||||
if (state->opt.force_stats) {
|
||||
os_clear();
|
||||
|
|
|
|||
|
|
@ -39,14 +39,6 @@ unsigned day_ago(time_t ref, time_t now)
|
|||
#define GRAPH_COLUMN 70
|
||||
#define GRAPH_ROW 15
|
||||
|
||||
static unsigned perc(uint64_t part, uint64_t total)
|
||||
{
|
||||
if (!total)
|
||||
return 0;
|
||||
|
||||
return (unsigned)(part * 100 / total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bit used to mark unscrubbed time info.
|
||||
*/
|
||||
|
|
@ -239,7 +231,7 @@ int state_status(struct snapraid_state* state)
|
|||
printf(" - ");
|
||||
} else {
|
||||
printf("%8" PRIu64, (disk_block_max - disk_block_count) * (uint64_t)state->block_size / GIGA);
|
||||
printf(" %3u%%", perc(disk_block_count, disk_block_max));
|
||||
printf(" %3u%%", muldiv(disk_block_count, 100, disk_block_max));
|
||||
}
|
||||
printf(" %s\n", disk->name);
|
||||
|
||||
|
|
@ -266,7 +258,7 @@ int state_status(struct snapraid_state* state)
|
|||
printf("%8.1f", (double)all_wasted / GIGA);
|
||||
printf("%8" PRIu64, file_size / GIGA);
|
||||
printf("%8" PRIu64, file_block_free * state->block_size / GIGA);
|
||||
printf(" %3u%%", perc(file_block_count, file_block_count + file_block_free));
|
||||
printf(" %3u%%", muldiv(file_block_count, 100, file_block_count + file_block_free));
|
||||
printf("\n");
|
||||
|
||||
/* warn about invalid data free info */
|
||||
|
|
@ -468,13 +460,13 @@ int state_status(struct snapraid_state* state)
|
|||
|
||||
if (unsynced_blocks) {
|
||||
printf("WARNING! The array is NOT fully synced.\n");
|
||||
printf("You have a sync in progress at %u%%.\n", (blockmax - unsynced_blocks) * 100 / blockmax);
|
||||
printf("You have a sync in progress at %u%%.\n", muldiv(blockmax - unsynced_blocks, 100, blockmax));
|
||||
} else {
|
||||
printf("No sync is in progress.\n");
|
||||
}
|
||||
|
||||
if (unscrubbed_blocks) {
|
||||
printf("The %u%% of the array is not scrubbed.\n", (unscrubbed_blocks * 100 + blockmax - 1) / blockmax);
|
||||
printf("The %u%% of the array is not scrubbed.\n", muldiv_upper(unscrubbed_blocks, 100, blockmax));
|
||||
} else {
|
||||
printf("The full array was scrubbed at least one time.\n");
|
||||
}
|
||||
|
|
@ -487,7 +479,7 @@ int state_status(struct snapraid_state* state)
|
|||
}
|
||||
|
||||
if (rehash) {
|
||||
printf("You have a rehash in progress at %u%%.\n", (count - rehash) * 100 / count);
|
||||
printf("You have a rehash in progress at %u%%.\n", muldiv(count - rehash, 100, count));
|
||||
} else {
|
||||
if (state->besthash != state->hash) {
|
||||
printf("No rehash is in progress, but for optimal performance one is recommended.\n");
|
||||
|
|
|
|||
|
|
@ -672,3 +672,22 @@ int lock_unlock(int f)
|
|||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/* muldiv */
|
||||
|
||||
unsigned muldiv(uint64_t v, uint64_t mul, uint64_t div)
|
||||
{
|
||||
if (!div)
|
||||
return 0;
|
||||
|
||||
return (uint32_t)(v * mul / div);
|
||||
}
|
||||
|
||||
unsigned muldiv_upper(uint64_t v, uint64_t mul, uint64_t div)
|
||||
{
|
||||
if (!div)
|
||||
return 0;
|
||||
|
||||
return (uint32_t)((v * mul + div - 1) / div);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -251,5 +251,10 @@ static inline int bit_vect_test(bit_vect_t* bit_vect, size_t off)
|
|||
return (bit_vect[off / BIT_VECT_SIZE] & mask) != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
/****************************************************************************/
|
||||
/* muldiv */
|
||||
|
||||
unsigned muldiv(uint64_t v, uint64_t mul, uint64_t div);
|
||||
unsigned muldiv_upper(uint64_t v, uint64_t mul, uint64_t div);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue