Disable some operations affected by hash collision

This only if we are working with a reduced hash length.
This commit is contained in:
Andrea Mazzoleni 2016-04-10 19:13:08 +02:00
parent ab7d4e896c
commit 5bf030c793
4 changed files with 31 additions and 5 deletions

View file

@ -501,7 +501,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign
/* try to fetch the old block using the old hash for CHG and DELETED blocks */
} else if ((block_state == BLOCK_STATE_CHG || block_state == BLOCK_STATE_DELETED)
&& hash_is_real(failed[j].block->hash)
&& hash_is_unique(failed[j].block->hash)
&& state_import_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0) {
/* note that from now the buffer is definitively lost */

View file

@ -536,11 +536,17 @@ int filter_content(tommy_list* contentlist, const char* path);
* Check if the specified hash is invalid.
*
* An invalid hash is represented with all bytes at 0x00.
*
* If working with reduced hash lengths, this function always return 0.
*/
static inline int hash_is_invalid(const unsigned char* hash)
{
int i;
/* if the hash is reduced, we cannot grant that it's a specific kind of hash */
if (BLOCK_HASH_SIZE != HASH_MAX)
return 0;
for (i = 0; i < BLOCK_HASH_SIZE; ++i)
if (hash[i] != 0x00)
return 0;
@ -552,11 +558,17 @@ static inline int hash_is_invalid(const unsigned char* hash)
* Check if the specified hash represent the zero block.
*
* A zero hash is represented with all bytes at 0xFF.
*
* If working with reduced hash lengths, this function always return 0.
*/
static inline int hash_is_zero(const unsigned char* hash)
{
int i;
/* if the hash is reduced, we cannot grant that it's a specific kind of hash */
if (BLOCK_HASH_SIZE != HASH_MAX)
return 0;
for (i = 0; i < BLOCK_HASH_SIZE; ++i)
if (hash[i] != 0xFF)
return 0;
@ -565,10 +577,16 @@ static inline int hash_is_zero(const unsigned char* hash)
}
/**
* Check if the specified hash is a real hash.
* Check if the specified hash is uniquievocally repesenting the data.
*
* If working with reduced hash lengths, this function always return 0.
*/
static inline int hash_is_real(const unsigned char* hash)
static inline int hash_is_unique(const unsigned char* hash)
{
/* if the hash is reduced, we cannot grant that it's a specific kind of hash */
if (BLOCK_HASH_SIZE != HASH_MAX)
return 0;
return !hash_is_zero(hash) && !hash_is_invalid(hash);
}

View file

@ -310,6 +310,14 @@ void state_import(struct snapraid_state* state, const char* dir)
msg_progress("Importing...\n");
/* if the hash is not full */
if (BLOCK_HASH_SIZE != HASH_MAX) {
/* LCOV_EXCL_START */
log_fatal("You cannot import files when using a reduced hash.\n");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
/* add the final slash */
pathimport(path, sizeof(path), dir);
pathslash(path, sizeof(path));

View file

@ -982,8 +982,8 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
/* have "parity_needs_to_be_updated" already at 1 */
assert(block_state_get(block) == BLOCK_STATE_CHG);
/* if there is an hash */
if (hash_is_real(block->hash)) {
/* if the hash represents the data uniquievocally */
if (hash_is_unique(block->hash)) {
/* check if the hash is changed */
if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
/* the block is different, and we must update parity */