summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Scherle2022-06-13 12:09:09 +0200
committerMichael Scherle2022-06-13 12:09:09 +0200
commitdf19826d98cf3eb4b31103314822e610f625397c (patch)
tree1cdd16b68698343af5ab1e9e11b6db1f20779141
parentremoved no longer needed free (diff)
downloaddnbd3-df19826d98cf3eb4b31103314822e610f625397c.tar.gz
dnbd3-df19826d98cf3eb4b31103314822e610f625397c.tar.xz
dnbd3-df19826d98cf3eb4b31103314822e610f625397c.zip
moved buffer from dnbd3_async_t to parent
-rw-r--r--src/cowtest/main.c38
-rw-r--r--src/fuse/connection.c22
-rw-r--r--src/fuse/connection.h5
-rw-r--r--src/fuse/cowfile.c23
-rw-r--r--src/fuse/cowfile.h7
-rw-r--r--src/fuse/main.c12
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 );
}
}