From df19826d98cf3eb4b31103314822e610f625397c Mon Sep 17 00:00:00 2001 From: Michael Scherle Date: Mon, 13 Jun 2022 12:09:09 +0200 Subject: moved buffer from dnbd3_async_t to parent --- src/cowtest/main.c | 38 +++++++++++++++++++++++++++----------- src/fuse/connection.c | 22 ++++++++++++++++++---- src/fuse/connection.h | 5 ++++- src/fuse/cowfile.c | 23 +++++++++-------------- src/fuse/cowfile.h | 7 +++++-- src/fuse/main.c | 12 ++++++------ 6 files changed, 69 insertions(+), 38 deletions(-) diff --git a/src/cowtest/main.c b/src/cowtest/main.c index c2c8643..66980fa 100644 --- a/src/cowtest/main.c +++ b/src/cowtest/main.c @@ -115,34 +115,50 @@ bool writeSizeTested( int fh, char *buf, ssize_t size, off_t off, char *error ) return true; } -bool verifyTestFirstBit() +bool verifySingleBit() { char buff[DNBD3_BLOCK_SIZE]; char expected[DNBD3_BLOCK_SIZE]; memset( expected, 0, DNBD3_BLOCK_SIZE ); expected[0] = 1; - if ( !readSizeTested( fh, buff, DNBD3_BLOCK_SIZE, 0, "FirstBit test Failed: read to small" ) ) + if ( !readSizeTested( fh, buff, DNBD3_BLOCK_SIZE, 0, "SingleBit test Failed: first read to small" ) ) return false; - if ( !compare( buff, expected, DNBD3_BLOCK_SIZE, "FirstBit test Failed: write not as expected" ) ) + if ( !compare( buff, expected, DNBD3_BLOCK_SIZE, "SingleBit test Failed: first write not as expected" ) ) return false; - printf( "testFirstBit successful!\n" ); + + expected[0] = 0; + expected[DNBD3_BLOCK_SIZE/2] = 1; + if ( !readSizeTested( fh, buff, DNBD3_BLOCK_SIZE, DNBD3_BLOCK_SIZE, "SingleBit test Failed: second read to small" ) ) + return false; + if ( !compare( buff, expected, DNBD3_BLOCK_SIZE, "SingleBit test Failed: second write not as expected" ) ) + return false; + printf( "testSingleBit successful!\n" ); return true; } -bool testFirstBit() +bool testSingleBit() { char buff[DNBD3_BLOCK_SIZE]; char expected[DNBD3_BLOCK_SIZE]; memset( expected, 0, DNBD3_BLOCK_SIZE ); - if ( !readSizeTested( fh, buff, DNBD3_BLOCK_SIZE, 0, "FirstBit test Failed: read to small" ) ) + if ( !readSizeTested( fh, buff, DNBD3_BLOCK_SIZE, 0, "SingleBit test Failed: first read to small" ) ) + return false; + + if ( !compare( buff, expected, DNBD3_BLOCK_SIZE, "SingleBit test Failed: initial read" ) ) + return false; + expected[0] = 1; + if ( !writeSizeTested( fh, expected, DNBD3_BLOCK_SIZE, 0, "SingleBit test Failed: first write failed" ) ) return false; - if ( !compare( buff, expected, DNBD3_BLOCK_SIZE, "FirstBit test Failed: initial read" ) ) + expected[0] = 0; + if ( !readSizeTested( fh, buff, DNBD3_BLOCK_SIZE, DNBD3_BLOCK_SIZE, "SingleBit test Failed: second read to small" ) ) + return false; + if ( !compare( buff, expected, DNBD3_BLOCK_SIZE, "SingleBit test Failed: second read" ) ) return false; expected[0] = 1; - if ( !writeSizeTested( fh, expected, DNBD3_BLOCK_SIZE, 0, "FirstBit test Failed: write failed" ) ) + if ( !writeSizeTested( fh, expected, 1, DNBD3_BLOCK_SIZE + DNBD3_BLOCK_SIZE / 2 , "SingleBit test Failed: second write failed" ) ) return false; - return verifyTestFirstBit(); + return verifySingleBit(); } bool verifyWriteOverTwoBlocks() @@ -441,7 +457,7 @@ void runTest( char *path ) strcpy( filePath, path ); printf( "file opened: %s\n", path ); - if ( !testFirstBit() ) + if ( !testSingleBit() ) return; if ( !writeOverTwoBlocks() ) return; @@ -467,7 +483,7 @@ void verifyTests( verify_test_t *tests ) { // offset, size, function - tests[0] = ( verify_test_t ){ 0, DNBD3_BLOCK_SIZE, verifyTestFirstBit }; + tests[0] = ( verify_test_t ){ 0, 2 * DNBD3_BLOCK_SIZE, verifySingleBit}; tests[1] = ( verify_test_t ){ DNBD3_BLOCK_SIZE * 3, DNBD3_BLOCK_SIZE * 3, verifyWriteOverTwoBlocks }; tests[2] = ( verify_test_t ){ DNBD3_BLOCK_SIZE * 11 - DNBD3_BLOCK_SIZE / 2, DNBD3_BLOCK_SIZE * 2, verifyWriteNotOnBlockBorder }; diff --git a/src/fuse/connection.c b/src/fuse/connection.c index 7e96d88..986393a 100644 --- a/src/fuse/connection.c +++ b/src/fuse/connection.c @@ -96,6 +96,7 @@ static void* connection_backgroundThread( void *something ); static void addAltServers(); static void sortAltServers(); static void probeAltServers(); +static size_t receiveRequest(const int sock, dnbd3_async_t* request ); static void switchConnection( int sockFd, alt_server_t *srv ); static void requestAltServers(); static bool throwDataAway( int sockFd, uint32_t amount ); @@ -398,7 +399,7 @@ static void* connection_receiveThreadMain( void *sockPtr ) } } else { // Found a match - const ssize_t ret = sock_recv( sockFd, request->buffer, request->length ); + const ssize_t ret = receiveRequest( sockFd, request); if ( ret != (ssize_t)request->length ) { logadd( LOG_DEBUG1, "receiving payload for a block reply failed" ); connection_read( request ); @@ -423,7 +424,7 @@ static void* connection_receiveThreadMain( void *sockPtr ) cowfile_handleCallback( request ); } else { - fuse_reply_buf( request->fuse_req, request->buffer, request->length ); + fuse_reply_buf( request->fuse_req, container_of( request, dnbd3_async_parent_t, request )->buffer, request->length ); free( request ); } } @@ -716,7 +717,7 @@ static void probeAltServers() } if ( request != NULL && removeRequest( request ) != NULL ) { // Request successfully removed from queue - const ssize_t ret = sock_recv( sock, request->buffer, request->length ); + ssize_t const ret = receiveRequest( sock, request); if ( ret != (ssize_t)request->length ) { logadd( LOG_DEBUG1, "%s probe: receiving payload for a block reply failed", hstr ); // Failure, add to queue again @@ -728,7 +729,7 @@ static void probeAltServers() cowfile_handleCallback( request ); } else { - fuse_reply_buf( request->fuse_req, request->buffer, request->length ); + fuse_reply_buf( request->fuse_req, container_of( request, dnbd3_async_parent_t, request )->buffer, request->length ); free( request ); } logadd( LOG_DEBUG1, "%s probe: Successful direct probe", hstr ); @@ -840,6 +841,19 @@ fail: } } +static size_t receiveRequest(const int sock, dnbd3_async_t* request ) { + if(useCow){ + cow_sub_request_t * cow_request = container_of( request, cow_sub_request_t, dRequest ); + if( cow_request->callback == readRemoteData){ + return sock_recv( sock, cow_request->buffer, request->length ); + } else{ + return sock_recv( sock, &cow_request->writeBuffer, request->length ); + } + } else { + return sock_recv( sock, container_of( request, dnbd3_async_parent_t, request )->buffer, request->length ); + } +} + static void switchConnection( int sockFd, alt_server_t *srv ) { struct sockaddr_storage addr; diff --git a/src/fuse/connection.h b/src/fuse/connection.h index 9f6447b..b22e3ce 100644 --- a/src/fuse/connection.h +++ b/src/fuse/connection.h @@ -22,9 +22,12 @@ typedef struct _dnbd3_async { uint64_t offset; uint32_t length; fuse_req_t fuse_req; - char buffer[]; // Must be last member! } dnbd3_async_t; +typedef struct _dnbd3_async_parent { + dnbd3_async_t request; + char buffer[]; // Must be last member! +} dnbd3_async_parent_t; bool connection_init( const char *hosts, const char *image, const uint16_t rid, const bool learnNewServers ); diff --git a/src/fuse/cowfile.c b/src/fuse/cowfile.c index c059812..365a9a4 100644 --- a/src/fuse/cowfile.c +++ b/src/fuse/cowfile.c @@ -911,9 +911,9 @@ static void finishWriteRequest( fuse_req_t req, cow_request_t *cowRequest ) static void writePaddedBlock( cow_sub_request_t *sRequest ) { //copy write Data - memcpy( ( sRequest->dRequest.buffer + ( sRequest->inBlockOffset % DNBD3_BLOCK_SIZE ) ), sRequest->buffer, + memcpy( ( sRequest->writeBuffer + ( sRequest->inBlockOffset % DNBD3_BLOCK_SIZE ) ), sRequest->writeSrc, sRequest->size ); - writeData( sRequest->dRequest.buffer, DNBD3_BLOCK_SIZE, (ssize_t)sRequest->size, sRequest->cowRequest, + writeData( sRequest->writeBuffer, DNBD3_BLOCK_SIZE, (ssize_t)sRequest->size, sRequest->cowRequest, sRequest->block, ( sRequest->inBlockOffset - ( sRequest->inBlockOffset % DNBD3_BLOCK_SIZE ) ) ); @@ -933,19 +933,18 @@ static void padBlockFromRemote( fuse_req_t req, off_t offset, cow_request_t *cow { if ( offset > (off_t)metadata->originalImageSize ) { //pad 0 and done - //TODO char buf[DNBD3_BLOCK_SIZE] = { 0 }; memcpy( buf, buffer, size ); writeData( buf, DNBD3_BLOCK_SIZE, (ssize_t)size, cowRequest, block, inBlockOffset ); return; } - cow_sub_request_t *sRequest = malloc( sizeof( cow_sub_request_t ) + DNBD3_BLOCK_SIZE ); + cow_sub_request_t *sRequest = malloc( sizeof( cow_sub_request_t ) + DNBD3_BLOCK_SIZE); sRequest->callback = writePaddedBlock; sRequest->inBlockOffset = inBlockOffset; sRequest->block = block; sRequest->size = size; - sRequest->buffer = buffer; + sRequest->writeSrc = buffer; sRequest->cowRequest = cowRequest; off_t start = offset - ( offset % DNBD3_BLOCK_SIZE ); @@ -975,12 +974,8 @@ void cowfile_handleCallback( dnbd3_async_t *request ) sRequest->callback( sRequest ); } -static void readRemoteData( cow_sub_request_t *sRequest ) +void readRemoteData( cow_sub_request_t *sRequest ) { - memcpy( sRequest->cowRequest->readBuffer + ( sRequest->dRequest.offset - sRequest->cowRequest->fuseRequestOffset ), - sRequest->dRequest.buffer, sRequest->dRequest.length ); - - atomic_fetch_add( &sRequest->cowRequest->bytesWorkedOn, sRequest->dRequest.length ); if ( atomic_fetch_sub( &sRequest->cowRequest->workCounter, 1 ) == 1 ) { @@ -1091,15 +1086,15 @@ void cowfile_write( fuse_req_t req, cow_request_t *cowRequest, off_t offset, siz * @param buffer into which the data is to be written * @param workCounter workCounter is increased by one and later reduced by one again when the request is completed. */ -static void readRemote( fuse_req_t req, off_t offset, ssize_t size, cow_request_t *cowRequest ) +static void readRemote( fuse_req_t req, off_t offset, ssize_t size, char * buffer, cow_request_t *cowRequest ) { - cow_sub_request_t *sRequest = malloc( sizeof( cow_sub_request_t ) + size ); + cow_sub_request_t *sRequest = malloc( sizeof( cow_sub_request_t )); sRequest->callback = readRemoteData; sRequest->dRequest.length = (uint32_t)size; sRequest->dRequest.offset = offset; sRequest->dRequest.fuse_req = req; sRequest->cowRequest = cowRequest; - + sRequest->buffer = buffer; atomic_fetch_add( &cowRequest->workCounter, 1 ); if ( !connection_read( &sRequest->dRequest ) ) { @@ -1185,7 +1180,7 @@ void cowfile_read( fuse_req_t req, size_t size, off_t offset ) if ( doRead || searchOffset >= endOffset ) { ssize_t sizeToRead = MIN( searchOffset, endOffset ) - lastReadOffset; if ( !isLocal ) { - readRemote( req, lastReadOffset, sizeToRead, cowRequest ); + readRemote( req, lastReadOffset, sizeToRead, cowRequest->readBuffer + ( lastReadOffset - offset ), cowRequest ); } else { // Compute the offset in the data file where the read starts off_t localRead = diff --git a/src/fuse/cowfile.h b/src/fuse/cowfile.h index 3ffa7b0..abcc85f 100644 --- a/src/fuse/cowfile.h +++ b/src/fuse/cowfile.h @@ -78,12 +78,13 @@ typedef struct cow_sub_request { size_t size; off_t inBlockOffset; - const char *buffer; + const char *writeSrc; + char * buffer; cow_block_metadata_t *block; cow_callback callback; cow_request_t *cowRequest; dnbd3_async_t dRequest; - + char writeBuffer[]; } cow_sub_request_t; typedef struct cow_curl_read_upload @@ -112,6 +113,8 @@ void cowfile_write( fuse_req_t req, cow_request_t *cowRequest, off_t offset, siz void cowfile_handleCallback( dnbd3_async_t *request ); +void readRemoteData( cow_sub_request_t *sRequest ); + int cow_printStats( char *buffer, const size_t len ); void cowfile_close(); diff --git a/src/fuse/main.c b/src/fuse/main.c index 8ee8221..926fcab 100644 --- a/src/fuse/main.c +++ b/src/fuse/main.c @@ -214,14 +214,14 @@ static void image_ll_read( fuse_req_t req, fuse_ino_t ino, size_t size, off_t of } - dnbd3_async_t *request = malloc( sizeof(dnbd3_async_t) + size ); - request->length = (uint32_t)size; - request->offset = offset; - request->fuse_req = req; + dnbd3_async_parent_t *parent = malloc( sizeof(dnbd3_async_parent_t) + size ); + parent->request.length = (uint32_t)size; + parent->request.offset = offset; + parent->request.fuse_req = req; - if ( !connection_read( request ) ) { + if ( !connection_read( &parent->request ) ) { fuse_reply_err( req, EIO ); - free( request ); + free( parent ); } } -- cgit v1.2.3-55-g7522