diff --git a/HISTORY b/HISTORY index 18daf87a..9305d051 100644 --- a/HISTORY +++ b/HISTORY @@ -1,6 +1,11 @@ SnapRAID HISTORY ================ +4.4 2013/10 +=========== + * Relaxed the check about small parity files, to allow to recover + after a failed sync before resizing the parity files. + 4.3 2013/10 =========== * Fixed the scrub command with the -p0 option. Now it really scrubs diff --git a/state.c b/state.c index 371fcd3e..6a849b58 100644 --- a/state.c +++ b/state.c @@ -38,7 +38,7 @@ void state_init(struct snapraid_state* state) state->pool_device = 0; state->lockfile[0] = 0; state->level = 1; /* default is the lowest protection */ - state->loaded_blockmax = 0; + state->loaded_paritymax = 0; state->no_conf = 0; tommy_list_init(&state->disklist); @@ -894,6 +894,7 @@ static void state_read_text(struct snapraid_state* state, const char* path, STRE struct snapraid_file* file; block_off_t blockidx; block_off_t blockmax; + block_off_t paritymax; unsigned line; unsigned count_file; unsigned count_block; @@ -906,6 +907,7 @@ static void state_read_text(struct snapraid_state* state, const char* path, STRE line = 1; blockidx = 0; blockmax = 0; + paritymax = 0; count_file = 0; count_block = 0; count_hardlink = 0; @@ -963,6 +965,10 @@ static void state_read_text(struct snapraid_state* state, const char* path, STRE switch (tag[0]) { case 'b' : block_state_set(block, BLOCK_STATE_BLK); + + /* keep track of the required parity size */ + if (v_pos + 1 > paritymax) + paritymax = v_pos + 1; break; case 'n' : block_state_set(block, BLOCK_STATE_NEW); @@ -1635,7 +1641,9 @@ static void state_read_text(struct snapraid_state* state, const char* path, STRE fprintf(stderr, "Internal inconsistency in parity size in '%s' at line %u\n", path, line); exit(EXIT_FAILURE); } - state->loaded_blockmax = blockmax; + + /* set the required parity size */ + state->loaded_paritymax = paritymax; if (state->opt.verbose) { printf("\tfile %u\n", count_file); @@ -2029,6 +2037,7 @@ static void decoding_error(const char* path, STREAM* f) static void state_read_binary(struct snapraid_state* state, const char* path, STREAM* f) { block_off_t blockmax; + block_off_t paritymax; unsigned count_file; unsigned count_block; unsigned count_hardlink; @@ -2041,6 +2050,7 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST uint32_t mapping_max; blockmax = 0; + paritymax = 0; count_file = 0; count_block = 0; count_hardlink = 0; @@ -2199,6 +2209,10 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST switch (c) { case 'b' : block_state_set(block, BLOCK_STATE_BLK); + + /* keep track of the required parity size */ + if (v_pos + 1 > paritymax) + paritymax = v_pos + 1; break; case 'n' : block_state_set(block, BLOCK_STATE_NEW); @@ -2686,7 +2700,9 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST fprintf(stderr, "Internal inconsistency in parity size in '%s' at offset %"PRIi64"\n", path, stell(f)); exit(EXIT_FAILURE); } - state->loaded_blockmax = blockmax; + + /* set the required parity size */ + state->loaded_paritymax = paritymax; if (state->opt.verbose) { printf("\tfile %u\n", count_file); diff --git a/state.h b/state.h index 6437770e..7a32bc81 100644 --- a/state.h +++ b/state.h @@ -88,7 +88,17 @@ struct snapraid_state { tommy_hashdyn importset; /**< Hashtable by hash of all the import blocks. */ tommy_hashdyn previmportset; /**< Hashtable by prevhash of all the import blocks. Valid only if we are in a rehash state. */ tommy_arrayof infoarr; /**< Block information array. */ - block_off_t loaded_blockmax; /**< Previous size of the parity file, computed from the loaded state. */ + + /** + * Required size of the parity file, computed from the loaded state. + * This size only counts BLK blocks, ignoring NEW, CHG and DELETED ones. + * + * In normal case it's also the blockmax size returned by parity_size(). + * In case of interrupted sync, this is the position + 1 of the last BLK block. + * Potentionally smaller than parity_size(). + */ + block_off_t loaded_paritymax; + time_t progress_start; /**< Start of processing for progress visualization. */ time_t progress_last; /**< Last update of progress visualization. */ time_t progress_interruption; /**< Start of the measure interruption. */ diff --git a/sync.c b/sync.c index da38cd8e..cdf21602 100644 --- a/sync.c +++ b/sync.c @@ -438,7 +438,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t blockmax = parity_size(state); size = blockmax * (data_off_t)state->block_size; - loaded_size = state->loaded_blockmax * (data_off_t)state->block_size; + loaded_size = state->loaded_paritymax * (data_off_t)state->block_size; if (blockstart > blockmax) { fprintf(stderr, "Error in the starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);