diff options
-rw-r--r-- | src/server/globals.c | 37 | ||||
-rw-r--r-- | src/server/globals.h | 6 | ||||
-rw-r--r-- | src/server/uplink.c | 21 |
3 files changed, 48 insertions, 16 deletions
diff --git a/src/server/globals.c b/src/server/globals.c index 8ef7aec..f6432cb 100644 --- a/src/server/globals.c +++ b/src/server/globals.c @@ -38,6 +38,7 @@ atomic_int _maxImages = SERVER_MAX_IMAGES; atomic_uint _maxPayload = 9000000; // 9MB atomic_uint_fast64_t _maxReplicationSize = (uint64_t)100000000000LL; atomic_uint _maxPrefetch = 262144; // 256KB +atomic_uint _minRequestSize = 0; /** * True when loading config the first time. Consecutive loads will @@ -89,6 +90,7 @@ static int ini_handler(void *custom UNUSED, const char* section, const char* key SAVE_TO_VAR_UINT( limits, maxPayload ); SAVE_TO_VAR_UINT64( limits, maxReplicationSize ); SAVE_TO_VAR_UINT( limits, maxPrefetch ); + SAVE_TO_VAR_UINT( limits, minRequestSize ); SAVE_TO_VAR_BOOL( dnbd3, pretendClient ); SAVE_TO_VAR_INT( dnbd3, autoFreeDiskSpaceDelay ); if ( strcmp( section, "dnbd3" ) == 0 && strcmp( key, "backgroundReplication" ) == 0 ) { @@ -134,16 +136,30 @@ void globals_loadConfig() if ( initialLoad ) { sanitizeFixedConfig(); } - if ( _backgroundReplication == BGR_FULL && _sparseFiles && _bgrMinClients < 5 ) { - logadd( LOG_WARNING, "Ignoring 'sparseFiles=true' since backgroundReplication is set to true and bgrMinClients is too low" ); - _sparseFiles = false; - } - if ( _bgrWindowSize < 1 ) { - _bgrWindowSize = 1; - } else if ( _bgrWindowSize > UPLINK_MAX_QUEUE - 10 ) { - _bgrWindowSize = UPLINK_MAX_QUEUE - 10; - logadd( LOG_MINOR, "Limiting bgrWindowSize to %d, because of UPLINK_MAX_QUEUE", - _bgrWindowSize ); + if ( _isProxy ) { + if ( _backgroundReplication == BGR_FULL && _sparseFiles && _bgrMinClients < 5 ) { + logadd( LOG_WARNING, "Ignoring 'sparseFiles=true' since backgroundReplication is set to true and bgrMinClients is too low" ); + _sparseFiles = false; + } + if ( _bgrWindowSize < 1 ) { + _bgrWindowSize = 1; + } else if ( _bgrWindowSize > UPLINK_MAX_QUEUE - 10 ) { + _bgrWindowSize = UPLINK_MAX_QUEUE - 10; + logadd( LOG_MINOR, "Limiting bgrWindowSize to %d, because of UPLINK_MAX_QUEUE", + _bgrWindowSize ); + } + if ( _maxPayload < 256 * 1024 ) { + logadd( LOG_WARNING, "maxPayload was increased to 256k" ); + _maxPayload = 256 * 1024; + } + if ( _maxPrefetch > _maxPayload ) { + logadd( LOG_WARNING, "Reducing maxPrefetch to maxPayload" ); + _maxPrefetch = _maxPayload; + } + if ( _minRequestSize > _maxPayload ) { + logadd( LOG_WARNING, "Reducing minRequestSize to maxPayload" ); + _minRequestSize = _maxPayload; + } } // Dump config as interpreted char buffer[2000]; @@ -354,6 +370,7 @@ size_t globals_dumpConfig(char *buffer, size_t size) PINT(maxPayload); PUINT64(maxReplicationSize); PINT(maxPrefetch); + PINT(minRequestSize); return size - rem; } diff --git a/src/server/globals.h b/src/server/globals.h index b255668..bde1184 100644 --- a/src/server/globals.h +++ b/src/server/globals.h @@ -341,6 +341,12 @@ extern atomic_int _autoFreeDiskSpaceDelay; extern atomic_uint _maxPrefetch; /** + * Use with care. Can severely degrade performance. + * Set either 0 or very high. + */ +extern atomic_uint _minRequestSize; + +/** * Load the server configuration. */ void globals_loadConfig(); diff --git a/src/server/uplink.c b/src/server/uplink.c index 4329663..8a83124 100644 --- a/src/server/uplink.c +++ b/src/server/uplink.c @@ -360,7 +360,7 @@ static bool uplink_requestInternal(dnbd3_uplink_t *uplink, void *data, uplink_ca if ( callback == NULL ) { // Set upper-most bit for replication requests that we fire // In client mode, at least set prefetch flag to prevent prefetch cascading - hops |= _pretendClient ? HOP_FLAG_PREFETCH : HOP_FLAG_BGR; + hops |= (uint8_t)( _pretendClient ? HOP_FLAG_PREFETCH : HOP_FLAG_BGR ); } req_t req, preReq; @@ -369,7 +369,7 @@ static bool uplink_requestInternal(dnbd3_uplink_t *uplink, void *data, uplink_ca const uint64_t end = start + length; req.start = start & ~(DNBD3_BLOCK_SIZE - 1); req.end = end; - /* Don't do this for now -- this breaks matching of prefetch jobs, since they'd + /* Don't do this -- this breaks matching of prefetch jobs, since they'd * be misaligned, and the next client request wouldn't match anything. * To improve this, we need to be able to attach a queue_client to multiple queue_entries * and then serve it once all the queue_entries are done (atomic_int in queue_client). @@ -379,11 +379,11 @@ static bool uplink_requestInternal(dnbd3_uplink_t *uplink, void *data, uplink_ca * and we should just drop all affected clients. Then as a next step, don't serve the * clients form the receive buffer, but just issue a normal sendfile() call after writing * the received data to the local cache. - if ( callback != NULL ) { + */ + if ( callback != NULL && _minRequestSize != 0 ) { // Not background replication request, extend request size extendRequest( req.start, &req.end, uplink->image, _minRequestSize ); } - */ req.end = (req.end + DNBD3_BLOCK_SIZE - 1) & ~(DNBD3_BLOCK_SIZE - 1); // Critical section - work with the queue mutex_lock( &uplink->queueLock ); @@ -889,9 +889,18 @@ static bool sendReplicationRequest(dnbd3_uplink_t *uplink) uplink->nextReplicationIndex = -1; break; } - const uint64_t offset = (uint64_t)replicationIndex * FILE_BYTES_PER_MAP_BYTE; - const uint32_t size = (uint32_t)MIN( image->virtualFilesize - offset, FILE_BYTES_PER_MAP_BYTE ); const uint64_t handle = ++uplink->queueId; + const uint64_t offset = (uint64_t)replicationIndex * FILE_BYTES_PER_MAP_BYTE; + uint32_t size = (uint32_t)MIN( image->virtualFilesize - offset, FILE_BYTES_PER_MAP_BYTE ); + // Extend the default 32k request size if _minRequestSize is > 32k + for ( size_t extra = 1; extra < ( _minRequestSize / FILE_BYTES_PER_MAP_BYTE ) + && offset + size < image->virtualFilesize + && _backgroundReplication == BGR_FULL; ++extra ) { + if ( atomic_load_explicit( &cache->map[replicationIndex+1], memory_order_relaxed ) == 0xff ) + break; // Hit complete 32k block, stop here + replicationIndex++; + size += (uint32_t)MIN( image->virtualFilesize - offset - size, FILE_BYTES_PER_MAP_BYTE ); + } if ( !uplink_requestInternal( uplink, NULL, NULL, handle, offset, size, 0 ) ) { logadd( LOG_DEBUG1, "Error sending background replication request to uplink server (%s:%d)", PIMG(uplink->image) ); |