summaryrefslogtreecommitdiffstats
path: root/src/server/uplink.c
diff options
context:
space:
mode:
authorSimon Rettberg2020-03-17 13:00:39 +0100
committerSimon Rettberg2020-03-17 13:00:39 +0100
commita2cbfba828bd8fcd5803d9786a3b3050823b27fc (patch)
tree0a898484e2f3fb21d7d0a2cf776e59d562691d61 /src/server/uplink.c
parent[SERVER] threadpool: Simplify get code, make debug code _DEBUG only (diff)
downloaddnbd3-a2cbfba828bd8fcd5803d9786a3b3050823b27fc.tar.gz
dnbd3-a2cbfba828bd8fcd5803d9786a3b3050823b27fc.tar.xz
dnbd3-a2cbfba828bd8fcd5803d9786a3b3050823b27fc.zip
[SERVER] Don't prefetch across hash blocks in BGS_HASHBLOCK mode
Diffstat (limited to 'src/server/uplink.c')
-rw-r--r--src/server/uplink.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/src/server/uplink.c b/src/server/uplink.c
index d6b319b..9bf48d3 100644
--- a/src/server/uplink.c
+++ b/src/server/uplink.c
@@ -44,7 +44,7 @@ typedef struct {
dnbd3_uplink_t *uplink;
uint64_t start;
uint32_t length;
-} prefetch_request_t;
+} prefetch_job_t;
#define assert_uplink_thread() assert( pthread_equal( uplink->thread, pthread_self() ) )
@@ -425,9 +425,12 @@ bool uplink_request(dnbd3_uplink_t *uplink, dnbd3_client_t *client, uint64_t han
success_ref:
if ( client != NULL ) {
// Was from client -- potential prefetch
+ // Same size as this request, but consider end of image...
uint32_t len = MIN( uplink->image->virtualFilesize - req.end, req.end - req.start );
- if ( len > 0 ) {
- prefetch_request_t *job = malloc( sizeof( *job ) );
+ // Also don't prefetch if we cross a hash block border and BGR mode == hashblock
+ if ( len > 0 && ( _backgroundReplication != BGR_HASHBLOCK
+ || req.start % HASH_BLOCK_SIZE == (req.end-1) % HASH_BLOCK_SIZE ) ) {
+ prefetch_job_t *job = malloc( sizeof( *job ) );
job->start = req.end;
job->length = len;
job->uplink = uplink;
@@ -450,7 +453,7 @@ fail_ref:
static void *prefetchForClient(void *data)
{
- prefetch_request_t *job = (prefetch_request_t*)data;
+ prefetch_job_t *job = (prefetch_job_t*)data;
dnbd3_cache_map_t *cache = ref_get_cachemap( job->uplink->image );
if ( cache != NULL ) {
if ( !image_isRangeCachedUnsafe( cache, job->start, job->start + job->length ) ) {
@@ -458,7 +461,7 @@ static void *prefetchForClient(void *data)
}
ref_put( &cache->reference );
}
- ref_put( &job->uplink->reference );
+ ref_put( &job->uplink->reference ); // Acquired in uplink_request
free( job );
return NULL;
}