diff --git a/HISTORY b/HISTORY index 1aa6803b..d98ad775 100644 --- a/HISTORY +++ b/HISTORY @@ -8,7 +8,8 @@ SnapRAID HISTORY * The 'list' command in verbose mode prints the full nanosecond timestamp precision. * After writing content files also sync their directory. - * Fix a invalid time computation that could result in future scrub times. + * Fix a invalid time computation that could result in future scrub dates. + Such dates are fixed automatically at the next scrub or sync. 11.2 2017/12 ============ diff --git a/cmdline/state.c b/cmdline/state.c index e730c220..b09fba23 100644 --- a/cmdline/state.c +++ b/cmdline/state.c @@ -2872,6 +2872,7 @@ struct state_write_thread_context { /* input */ block_off_t blockmax; time_t info_oldest; + time_t info_now; int info_has_rehash; STREAM* f; /* output */ @@ -2888,6 +2889,7 @@ static void* state_write_thread(void* arg) struct snapraid_state* state = context->state; block_off_t blockmax = context->blockmax; time_t info_oldest = context->info_oldest; + time_t info_now = context->info_now; int info_has_rehash = context->info_has_rehash; STREAM* f = context->f; uint32_t crc; @@ -3278,11 +3280,17 @@ static void* state_write_thread(void* arg) flag |= 8; sputb32(flag, f); + t = info_get_time(info); + + /* truncate any time that is in the future */ + if (t > info_now) + t = info_now; + /* the oldest info is computed only on required blocks, so it may not be the absolute oldest */ - if (info_get_time(info) >= info_oldest) - t = info_get_time(info) - info_oldest; - else + if (t < info_oldest) t = 0; + else + t -= info_oldest; sputb32(t, f); } else { @@ -3358,6 +3366,7 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc) tommy_node* i; block_off_t blockmax; time_t info_oldest; + time_t info_now; int info_has_rehash; int mapping_idx; block_off_t idx; @@ -3376,6 +3385,7 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc) /* clear the info for unused blocks */ /* and get some other info */ info_oldest = 0; /* oldest time in info */ + info_now = time(0); /* get the present time */ info_has_rehash = 0; /* if there is a rehash info */ for (idx = 0; idx < blockmax; ++idx) { /* if the position is used */ @@ -3466,6 +3476,7 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc) context->state = state; context->blockmax = blockmax; context->info_oldest = info_oldest; + context->info_now = info_now; context->info_has_rehash = info_has_rehash; context->f = f; @@ -3607,6 +3618,7 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc) context->state = state; context->blockmax = blockmax; context->info_oldest = info_oldest; + context->info_now = info_now; context->info_has_rehash = info_has_rehash; context->f = f; diff --git a/cmdline/status.c b/cmdline/status.c index a6d769cb..9f621de1 100644 --- a/cmdline/status.c +++ b/cmdline/status.c @@ -29,6 +29,10 @@ unsigned day_ago(time_t ref, time_t now) { + /* in case some dates is in the future */ + if (now < ref) + return 0; + return (now - ref) / (24 * 3600); } @@ -458,6 +462,10 @@ int state_status(struct snapraid_state* state) printf("\n"); + if (newest > now) { + printf("WARNING! You have scrub dates in the future! The next sync/scrub will truncate them!\n"); + } + 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);