From 3d0c89fccf14599d156696d74224a4fbe0787777 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 29 Oct 2019 17:55:20 +0100 Subject: [SERVER] Fix checking images without cache map --- src/server/image.c | 18 +++++++++++------- src/server/image.h | 2 +- src/server/integrity.c | 4 ++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/server/image.c b/src/server/image.c index 6259e38..9581a92 100644 --- a/src/server/image.c +++ b/src/server/image.c @@ -160,7 +160,7 @@ void image_updateCachemap(dnbd3_image_t *image, uint64_t start, uint64_t end, co end = (end + HASH_BLOCK_SIZE - 1) & ~(uint64_t)(HASH_BLOCK_SIZE - 1); for ( pos = start; pos < end; pos += HASH_BLOCK_SIZE ) { const int block = (int)( pos / HASH_BLOCK_SIZE ); - if ( image_isHashBlockComplete( cache->map, block, image->realFilesize ) ) { + if ( image_isHashBlockComplete( cache, block, image->realFilesize ) ) { integrity_check( image, block, false ); } } @@ -651,9 +651,11 @@ static dnbd3_image_t* image_free(dnbd3_image_t *image) return NULL ; } -bool image_isHashBlockComplete(atomic_uint_least8_t * const cacheMap, const uint64_t block, const uint64_t realFilesize) +bool image_isHashBlockComplete(dnbd3_cache_map_t * const cache, const uint64_t block, const uint64_t realFilesize) { - if ( cacheMap == NULL ) return true; + if ( cache == NULL ) + return true; + const atomic_uint_least8_t *cacheMap = cache->map; const uint64_t end = (block + 1) * HASH_BLOCK_SIZE; if ( end <= realFilesize ) { // Trivial case: block in question is not the last block (well, or image size is multiple of HASH_BLOCK_SIZE) @@ -1039,10 +1041,10 @@ static void image_checkRandomBlocks(dnbd3_image_t *image, const int count) int blocks[count]; int index = 0, j; int block; - if ( image_isHashBlockComplete( cache->map, 0, image->virtualFilesize ) ) { + if ( image_isHashBlockComplete( cache, 0, image->virtualFilesize ) ) { blocks[index++] = 0; } - if ( hashBlocks > 1 && image_isHashBlockComplete( cache->map, hashBlocks - 1, image->virtualFilesize ) ) { + if ( hashBlocks > 1 && image_isHashBlockComplete( cache, hashBlocks - 1, image->virtualFilesize ) ) { blocks[index++] = hashBlocks - 1; } int tries = count * 5; // Try only so many times to find a non-duplicate complete block @@ -1052,12 +1054,14 @@ static void image_checkRandomBlocks(dnbd3_image_t *image, const int count) if ( blocks[j] == block ) goto while_end; } // Block complete? If yes, add to list - if ( image_isHashBlockComplete( cache->map, block, image->virtualFilesize ) ) { + if ( image_isHashBlockComplete( cache, block, image->virtualFilesize ) ) { blocks[index++] = block; } while_end: ; } - ref_put( &cache->reference ); + if ( cache != NULL ) { + ref_put( &cache->reference ); + } for ( int i = 0; i < index; ++i ) { integrity_check( image, blocks[i], true ); } diff --git a/src/server/image.h b/src/server/image.h index 449e31f..89791fc 100644 --- a/src/server/image.h +++ b/src/server/image.h @@ -9,7 +9,7 @@ void image_serverStartup(); bool image_isComplete(dnbd3_image_t *image); -bool image_isHashBlockComplete(atomic_uint_least8_t * const cacheMap, const uint64_t block, const uint64_t fileSize); +bool image_isHashBlockComplete(dnbd3_cache_map_t * const cache, const uint64_t block, const uint64_t fileSize); void image_updateCachemap(dnbd3_image_t *image, uint64_t start, uint64_t end, const bool set); diff --git a/src/server/integrity.c b/src/server/integrity.c index 1fbd9dc..4006dfc 100644 --- a/src/server/integrity.c +++ b/src/server/integrity.c @@ -174,7 +174,7 @@ static void* integrity_main(void * data UNUSED) dnbd3_cache_map_t *cache = ref_get_cachemap( image ); if ( cache != NULL ) { // When checking full image, skip incomplete blocks, otherwise assume block is complete - complete = image_isHashBlockComplete( cache->map, blocks[0], fileSize ); + complete = image_isHashBlockComplete( cache, blocks[0], fileSize ); ref_put( &cache->reference ); } } @@ -205,7 +205,7 @@ static void* integrity_main(void * data UNUSED) bool iscomplete = true; dnbd3_cache_map_t *cache = ref_get_cachemap( image ); if ( cache != NULL ) { - iscomplete = image_isHashBlockComplete( cache->map, blocks[0], fileSize ); + iscomplete = image_isHashBlockComplete( cache, blocks[0], fileSize ); ref_put( &cache->reference ); } logadd( LOG_WARNING, "Hash check for block %d of %s failed (complete: was: %d, is: %d)", blocks[0], image->name, (int)complete, (int)iscomplete ); -- cgit v1.2.3-55-g7522