diff --git a/HISTORY b/HISTORY index 9afb8127..41024c8c 100644 --- a/HISTORY +++ b/HISTORY @@ -27,6 +27,11 @@ SnapRAID HISTORY at the new "list" one. * Reduced memory usage avoiding to allocate unnecessary memory. +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 313bab8e..16bc7a3b 100644 --- a/state.c +++ b/state.c @@ -65,7 +65,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->clear_undeterminate_hash = 0; state->no_conf = 0; @@ -892,6 +892,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; @@ -904,6 +905,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; @@ -961,6 +963,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); @@ -1643,7 +1649,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("%8u files\n", count_file); @@ -2037,6 +2045,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; @@ -2049,6 +2058,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; @@ -2207,6 +2217,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); @@ -2703,7 +2717,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("%8u files\n", count_file); diff --git a/state.h b/state.h index fc5e77ee..a8403be8 100644 --- a/state.h +++ b/state.h @@ -104,7 +104,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_arrayblkof 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; + int clear_undeterminate_hash; /**< Clear all the hash from CHG and DELETED blocks when reading the state from an incomplete sync. */ time_t progress_start; /**< Start of processing for progress visualization. */ time_t progress_last; /**< Last update of progress visualization. */ diff --git a/sync.c b/sync.c index 14550a10..15cf888b 100644 --- a/sync.c +++ b/sync.c @@ -504,7 +504,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);