summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2018-08-14 14:24:18 +0200
committerSimon Rettberg2018-08-14 14:24:18 +0200
commit2986340a090875f87693401fb07f5bbc4100a824 (patch)
tree92ba5a70e40241b9f66909a9ce81226cefb892d6
parent[SERVER] Use atomic vars for uplink byte counters (diff)
downloaddnbd3-2986340a090875f87693401fb07f5bbc4100a824.tar.gz
dnbd3-2986340a090875f87693401fb07f5bbc4100a824.tar.xz
dnbd3-2986340a090875f87693401fb07f5bbc4100a824.zip
[SERVER] Fix last block replicating indefinitely in hasblock mode
-rw-r--r--src/server/uplink.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/src/server/uplink.c b/src/server/uplink.c
index 76ffdbb..ef8f893 100644
--- a/src/server/uplink.c
+++ b/src/server/uplink.c
@@ -618,7 +618,7 @@ static void uplink_sendReplicationRequest(dnbd3_connection_t *link)
/**
* find next index into cache_map that corresponds to the beginning
- * if a hash block which is neither completely empty nor completely
+ * of a hash block which is neither completely empty nor completely
* replicated yet. Returns -1 if no match.
*/
static int uplink_findNextIncompleteHashBlock(dnbd3_connection_t *link, const int startMapIndex)
@@ -632,7 +632,9 @@ static int uplink_findNextIncompleteHashBlock(dnbd3_connection_t *link, const in
const int start = ( startMapIndex & MAP_INDEX_HASH_START_MASK );
for (j = 0; j < mapBytes; ++j) {
const int i = ( start + j ) % mapBytes;
- if ( cache_map[i] != 0 && cache_map[i] != 0xff ) {
+ const bool isFull = cache_map[i] == 0xff || ( i + 1 == mapBytes && link->replicatedLastBlock );
+ const bool isEmpty = cache_map[i] == 0;
+ if ( !isEmpty && !isFull ) {
// Neither full nor empty, replicate
if ( retval == -1 ) {
retval = i;
@@ -641,13 +643,13 @@ static int uplink_findNextIncompleteHashBlock(dnbd3_connection_t *link, const in
}
if ( ( i & MAP_INDEX_HASH_START_MASK ) == i ) {
// Reset state if we just crossed into the next hash chunk
- retval = ( cache_map[i] == 0 ) ? ( i ) : ( -1 );
- } else if ( cache_map[i] == 0xff ) {
+ retval = ( isEmpty ) ? ( i ) : ( -1 );
+ } else if ( isFull ) {
if ( retval != -1 ) {
// It's a full one, previous one was empty -> replicate
break;
}
- } else { // ( cache_map[i] == 0 )
+ } else if ( isEmpty ) {
if ( retval == -1 ) { // Previous one was full -> replicate
retval = i;
break;