summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2014-01-11 16:23:26 +0100
committerSimon Rettberg2014-01-11 16:23:26 +0100
commit1f34fdd347b99c1e59ea8ed468fdf85a7a7c2775 (patch)
tree3dd9e30da97487653f6e2287fd2d1147f927ca7b
parent[SERVER] Let's try compiler detection again (diff)
downloaddnbd3-1f34fdd347b99c1e59ea8ed468fdf85a7a7c2775.tar.gz
dnbd3-1f34fdd347b99c1e59ea8ed468fdf85a7a7c2775.tar.xz
dnbd3-1f34fdd347b99c1e59ea8ed468fdf85a7a7c2775.zip
Fixed the amazing infinite loop I introduced when refactoring
-rw-r--r--src/server/image.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/src/server/image.c b/src/server/image.c
index 2ee8aa2..ad04b2a 100644
--- a/src/server/image.c
+++ b/src/server/image.c
@@ -90,6 +90,7 @@ int image_isComplete(dnbd3_image_t *image)
}
return complete;
}
+
/**
* Update cache-map of given image for the given byte range
* start (inclusive) - end (exclusive)
@@ -756,19 +757,28 @@ static uint32_t* image_loadCrcList(const char * const imagePath, const int64_t f
static int image_checkRandomBlocks(const int count, int fdImage, const int64_t fileSize, uint32_t * const crc32list,
uint8_t * const cache_map)
{
- // This checks the first block and two random blocks (which might accidentally be the same)
- // for corruption via the known crc32 list. This is very sloppy and is merely supposed
- // to detect accidental corruption due to broken dnbd3-proxy functionality or file system
+ // This checks the first block and (up to) count - 1 random blocks for corruption
+ // via the known crc32 list. This is very sloppy and is merely supposed to detect
+ // accidental corruption due to broken dnbd3-proxy functionality or file system
// corruption.
+ assert( count > 0 );
const int hashBlocks = IMGSIZE_TO_HASHBLOCKS( fileSize );
- int blocks[count + 1], index = 0, block; // = { 0, rand() % blcks, rand() % blcks, -1 };
+ int blocks[count + 1];
+ int index = 0, j;
+ int block;
if ( image_isHashBlockComplete( cache_map, 0, fileSize ) ) blocks[index++] = 0;
- while ( index + 1 < count ) {
- block = rand() % hashBlocks;
+ int tries = count * 5; // Try only so many times to find a non-duplicate complete block
+ while ( index + 1 < count && --tries > 0 ) {
+ block = rand() % hashBlocks; // Random block
+ for ( j = 0; j < index; ++j ) { // Random block already in list?
+ if ( blocks[j] == block ) goto while_end;
+ }
+ // Block complete? If yes, add to list
if ( image_isHashBlockComplete( cache_map, block, fileSize ) ) blocks[index++] = block;
+while_end: ;
}
- if ( index < count ) blocks[index] = -1;
- return image_checkBlocksCrc32( fdImage, crc32list, blocks, fileSize );
+ blocks[MIN(index, count)] = -1; // End of array has to be marked by a -1
+ return image_checkBlocksCrc32( fdImage, crc32list, blocks, fileSize ); // Return result of check
}
/**