summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Scherle2022-04-12 18:30:57 +0200
committerMichael Scherle2022-04-12 18:30:57 +0200
commitc5ba8d71817e285337dafcb3ae6f47982abfb1e3 (patch)
tree95576c5f9773a9ed7bef47e11ef32c367b5c3513
parentmultible bugfixes, test can verify existing file (diff)
downloaddnbd3-c5ba8d71817e285337dafcb3ae6f47982abfb1e3.tar.gz
dnbd3-c5ba8d71817e285337dafcb3ae6f47982abfb1e3.tar.xz
dnbd3-c5ba8d71817e285337dafcb3ae6f47982abfb1e3.zip
changed to use container_of and callbacks
-rw-r--r--src/fuse/connection.c14
-rw-r--r--src/fuse/connection.h9
-rw-r--r--src/fuse/cowfile.c132
-rw-r--r--src/fuse/cowfile.h23
-rw-r--r--src/fuse/main.c13
-rw-r--r--src/fuse/main.h5
6 files changed, 103 insertions, 93 deletions
diff --git a/src/fuse/connection.c b/src/fuse/connection.c
index ff77794..20c57ae 100644
--- a/src/fuse/connection.c
+++ b/src/fuse/connection.c
@@ -6,6 +6,8 @@
#include <dnbd3/shared/sockhelper.h>
#include <dnbd3/shared/log.h>
+#include "main.h"
+#include "cowfile.h"
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
@@ -406,10 +408,8 @@ static void* connection_receiveThreadMain( void *sockPtr )
}
unlock_rw( &altLock );
}
- if( request->cow_write != NULL ) {
- cowfile_writePaddedBlock(request );
- } else if( request->cow != NULL ) {
- cowFile_readRemoteData( request );
+ if(useCow){
+ cowFile_handleCallback( request );
}
else {
fuse_reply_buf( request->fuse_req, request->buffer, request->length );
@@ -714,10 +714,8 @@ static void probeAltServers()
goto fail;
}
// Success, reply to fuse
- if( request->cow_write != NULL ) {
- cowfile_writePaddedBlock(request );
- } else if( request->cow != NULL ) {
- cowFile_readRemoteData( request );
+ if(useCow){
+ cowFile_handleCallback(request);
}
else {
fuse_reply_buf( request->fuse_req, request->buffer, request->length );
diff --git a/src/fuse/connection.h b/src/fuse/connection.h
index 51173ad..e5fe89b 100644
--- a/src/fuse/connection.h
+++ b/src/fuse/connection.h
@@ -12,23 +12,20 @@
#include <fuse_lowlevel.h>
+
extern atomic_bool keepRunning;
struct _dnbd3_async;
-typedef struct cow_request cow_request_t;
-typedef struct cow_write_request cow_write_request_t;
-
typedef struct _dnbd3_async {
struct _dnbd3_async *next; // Next in this linked list (provate field, not set by caller)
ticks time; // When request was put on wire, 0 if not measuring
uint64_t offset;
uint32_t length;
fuse_req_t fuse_req;
- cow_request_t *cow;
- cow_write_request_t *cow_write;
- char* buffer;
+ char buffer[]; // Must be last member!
} dnbd3_async_t;
+
bool connection_init( const char *hosts, const char *image, const uint16_t rid, const bool learnNewServers );
bool connection_initThreads();
diff --git a/src/fuse/cowfile.c b/src/fuse/cowfile.c
index d020aec..ae6f095 100644
--- a/src/fuse/cowfile.c
+++ b/src/fuse/cowfile.c
@@ -388,75 +388,87 @@ static void finishWriteRequest( fuse_req_t req, cow_request_t *cowRequest )
free( cowRequest );
}
+static void writePaddedBlock( cow_sub_request_t *sRequest )
+{
+ //copy write Data
+ memcpy( ( sRequest->dRequest.buffer + ( sRequest->inBlockOffset % DNBD3_BLOCK_SIZE ) ), sRequest->buffer,
+ sRequest->size );
+ writeData( sRequest->dRequest.buffer, DNBD3_BLOCK_SIZE, (ssize_t)sRequest->size, sRequest->cowRequest,
+ sRequest->block, ( sRequest->inBlockOffset - ( sRequest->inBlockOffset % DNBD3_BLOCK_SIZE ) ) );
+
+
+ if ( atomic_fetch_sub( &sRequest->cowRequest->workCounter, 1 ) == 1 ) {
+ finishWriteRequest( sRequest->dRequest.fuse_req, sRequest->cowRequest );
+ }
+ free( sRequest );
+}
// TODO if > remote pad 0
/**
* @brief
*
*/
-static void padBlockFromRemote(
- fuse_req_t req, off_t offset, cow_request_t *cowRequest, cow_write_request_t *cowWriteRequest )
+static void padBlockFromRemote( fuse_req_t req, off_t offset, cow_request_t *cowRequest, char *buffer, size_t size,
+ cow_block_metadata_t *block, off_t inBlockOffset )
{
if ( offset > (off_t)metadata->originalImageSize ) {
//pad 0 and done
char buffer[DNBD3_BLOCK_SIZE] = { 0 };
- memcpy( buffer, cowWriteRequest->buffer, cowWriteRequest->size );
+ memcpy( buffer, buffer, size );
- writeData( buffer, DNBD3_BLOCK_SIZE, (ssize_t)cowWriteRequest->size, cowRequest, cowWriteRequest->block,
- cowWriteRequest->inBlockOffset );
- free( cowWriteRequest );
+ writeData( buffer, DNBD3_BLOCK_SIZE, (ssize_t)size, cowRequest, block, inBlockOffset );
return;
}
-
+ 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->cowRequest = cowRequest;
off_t start = offset - ( offset % DNBD3_BLOCK_SIZE );
- dnbd3_async_t *request = malloc( sizeof( dnbd3_async_t ) );
- request->buffer = calloc( DNBD3_BLOCK_SIZE, sizeof( char ) );
- request->length = DNBD3_BLOCK_SIZE;
- request->offset = start;
- request->fuse_req = req;
- request->cow = cowRequest;
- request->cow_write = cowWriteRequest;
+ sRequest->dRequest.length = DNBD3_BLOCK_SIZE;
+ sRequest->dRequest.offset = start;
+ sRequest->dRequest.fuse_req = req;
+ sRequest->cowRequest = cowRequest;
+
if ( ( (size_t)( offset + DNBD3_BLOCK_SIZE ) ) > metadata->originalImageSize ) {
- request->length = (uint32_t)MIN( DNBD3_BLOCK_SIZE, offset + DNBD3_BLOCK_SIZE - metadata->originalImageSize );
+ sRequest->dRequest.length =
+ (uint32_t)MIN( DNBD3_BLOCK_SIZE, offset + DNBD3_BLOCK_SIZE - metadata->originalImageSize );
}
atomic_fetch_add( &cowRequest->workCounter, 1 );
- if ( !connection_read( request ) ) {
+ if ( !connection_read( &sRequest->dRequest ) ) {
atomic_fetch_sub( &cowRequest->workCounter, 1 );
// todo check if not now
cowRequest->errorCode = EIO;
- free( request );
+ free( sRequest );
return;
}
}
-void cowfile_writePaddedBlock( dnbd3_async_t *request )
+
+void cowFile_handleCallback( dnbd3_async_t *request )
{
- //copy write Data
- memcpy( ( request->buffer + ( request->cow_write->inBlockOffset % DNBD3_BLOCK_SIZE ) ), request->cow_write->buffer,
- request->cow_write->size );
- writeData( request->buffer, DNBD3_BLOCK_SIZE, (ssize_t)request->cow_write->size, request->cow,
- request->cow_write->block,
- ( request->cow_write->inBlockOffset - ( request->cow_write->inBlockOffset % DNBD3_BLOCK_SIZE ) ) );
-
- free( request->cow_write );
- if ( atomic_fetch_sub( &request->cow->workCounter, 1 ) == 1 ) {
- finishWriteRequest( request->fuse_req, request->cow );
- }
- free( request->buffer );
- free( request );
+ cow_sub_request_t *sRequest = container_of( request, cow_sub_request_t, dRequest );
+ sRequest->callback( sRequest );
}
-
-void cowFile_readRemoteData( dnbd3_async_t *request )
+static void readRemoteData( cow_sub_request_t *sRequest )
{
- atomic_fetch_add( &request->cow->bytesWorkedOn, request->length );
- if ( atomic_fetch_sub( &request->cow->workCounter, 1 ) == 1 ) {
- fuse_reply_buf( request->fuse_req, request->cow->readBuffer, request->cow->bytesWorkedOn );
- free( request->cow->readBuffer );
- free( request->cow );
+ 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 ) {
+ fuse_reply_buf(
+ sRequest->dRequest.fuse_req, sRequest->cowRequest->readBuffer, sRequest->cowRequest->bytesWorkedOn );
+ free( sRequest->cowRequest->readBuffer );
+ free( sRequest->cowRequest );
}
- free( request );
+ free( sRequest );
}
@@ -506,12 +518,8 @@ void cowfile_write( fuse_req_t req, cow_request_t *cowRequest, off_t offset, siz
&& !checkBit( metaBlock->bitfield, (int)( inBlockOffset / DNBD3_BLOCK_SIZE ) ) ) {
// write remote
size_t padSize = MIN( sizeToWriteToBlock, DNBD3_BLOCK_SIZE - ( (size_t)currentOffset % DNBD3_BLOCK_SIZE ) );
- cow_write_request_t *cowWriteRequest = malloc( sizeof( cow_write_request_t ) );
- cowWriteRequest->inBlockOffset = (off_t)inBlockOffset;
- cowWriteRequest->block = metaBlock;
- cowWriteRequest->size = padSize;
- cowWriteRequest->buffer = cowRequest->writeBuffer + ( ( currentOffset - offset ) * !cowRequest->replyAttr );
- padBlockFromRemote( req, offset, cowRequest, cowWriteRequest );
+ char *sbuf = cowRequest->writeBuffer + ( ( currentOffset - offset ) * !cowRequest->replyAttr );
+ padBlockFromRemote( req, offset, cowRequest, sbuf, padSize, metaBlock, (off_t)inBlockOffset );
currentOffset += padSize;
continue;
}
@@ -522,13 +530,9 @@ void cowfile_write( fuse_req_t req, cow_request_t *cowRequest, off_t offset, siz
off_t padStartOffset = currentEndOffset - ( currentEndOffset % 4096 );
off_t inBlockPadStartOffset = padStartOffset - metaBlockStartOffset;
if ( !checkBit( metaBlock->bitfield, (int)( inBlockPadStartOffset / DNBD3_BLOCK_SIZE ) ) ) {
- cow_write_request_t *cowWriteRequest = malloc( sizeof( cow_write_request_t ) );
- cowWriteRequest->inBlockOffset = inBlockPadStartOffset;
- cowWriteRequest->block = metaBlock;
- cowWriteRequest->size = (currentEndOffset)-padStartOffset;
- cowWriteRequest->buffer =
- cowRequest->writeBuffer + ( ( padStartOffset - offset ) * !cowRequest->replyAttr );
- padBlockFromRemote( req, padStartOffset, cowRequest, cowWriteRequest );
+ char *sbuf = cowRequest->writeBuffer + ( ( padStartOffset - offset ) * !cowRequest->replyAttr );
+ padBlockFromRemote( req, padStartOffset, cowRequest, sbuf, (currentEndOffset)-padStartOffset, metaBlock,
+ inBlockPadStartOffset );
sizeToWriteToBlock -= (currentEndOffset)-padStartOffset;
@@ -567,21 +571,22 @@ 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, char *buffer, cow_request_t *cowRequest )
+static void readRemote( fuse_req_t req, off_t offset, ssize_t size, cow_request_t *cowRequest )
{
- dnbd3_async_t *request = malloc( sizeof( dnbd3_async_t ) );
- request->buffer = buffer;
- request->length = (uint32_t)size;
- request->offset = offset;
- request->fuse_req = req;
- request->cow = cowRequest;
- request->cow_write = NULL;
+ cow_sub_request_t *sRequest = malloc( sizeof( cow_sub_request_t ) + size );
+ sRequest->callback = readRemoteData;
+ sRequest->dRequest.length = (uint32_t)size;
+ sRequest->dRequest.offset = offset;
+ sRequest->dRequest.fuse_req = req;
+ sRequest->cowRequest = cowRequest;
+
+
atomic_fetch_add( &cowRequest->workCounter, 1 );
- if ( !connection_read( request ) ) {
+ if ( !connection_read( &sRequest->dRequest ) ) {
atomic_fetch_sub( &cowRequest->workCounter, 1 );
//TODO ChECK IF NOT 0 Now
cowRequest->errorCode = EIO;
- free( request );
+ free( sRequest );
return;
}
}
@@ -661,8 +666,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->readBuffer + ( lastReadOffset - offset ), cowRequest );
+ readRemote( req, lastReadOffset, sizeToRead, 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 43101e2..d28158c 100644
--- a/src/fuse/cowfile.h
+++ b/src/fuse/cowfile.h
@@ -1,6 +1,9 @@
#ifndef _COWFILE_H_
#define _COWFILE_H_
+
+#include "connection.h"
+#include "main.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdatomic.h>
@@ -9,12 +12,12 @@
#include <string.h>
#include <pthread.h>
#include <errno.h>
-#include "main.h"
+
#define COW_METADAT_STORAGE_CAPACITY ( COW_BITFIELD_SIZE * DNBD3_BLOCK_SIZE )
#define COW_L2_SIZE 1024
#define COW_L2_STORAGE_CAPACITY ( COW_L2_SIZE * COW_METADAT_STORAGE_CAPACITY )
-
+#define container_of( ptr, type, member ) ( (type *)( (char *)( ptr ) - (char *)&( ( (type *)NULL )->member ) ) )
#define COW_METADATA_HEADER_SIZE 280
typedef struct __attribute__( ( packed ) ) cowfile_metadata_header
@@ -59,14 +62,21 @@ typedef struct cow_request
struct fuse_file_info *fi;
} cow_request_t;
-typedef struct cow_write_request
+typedef struct cow_sub_request cow_sub_request_t;
+typedef void ( *cow_callback )( cow_sub_request_t *sRequest );
+
+
+typedef struct cow_sub_request
{
- const char *buffer;
size_t size;
off_t inBlockOffset;
+ const char *buffer;
cow_block_metadata_t *block;
+ cow_callback callback;
+ cow_request_t *cowRequest;
+ dnbd3_async_t dRequest;
-} cow_write_request_t;
+} cow_sub_request_t;
typedef int32_t l1;
@@ -77,6 +87,7 @@ bool cowfile_load( char *path, size_t **imageSizePtr );
void cowfile_read( fuse_req_t req, size_t size, off_t offset );
void cowfile_write( fuse_req_t req, cow_request_t *cowRequest, off_t offset, size_t size );
-size_t cowfile_append( char *buffer, uint64_t offset, uint64_t size );
+void cowFile_handleCallback( dnbd3_async_t *request );
+
#endif /* COWFILE_H_ */ \ No newline at end of file
diff --git a/src/fuse/main.c b/src/fuse/main.c
index b7a4a9b..5d37813 100644
--- a/src/fuse/main.c
+++ b/src/fuse/main.c
@@ -16,7 +16,7 @@ static const char *IMAGE_NAME = "img";
static const char *STATS_NAME = "status";
static struct fuse_session *_fuseSession = NULL;
-
+bool useCow = false;
static uint64_t imageSize;
static uint64_t *imageSizePtr =&imageSize;
@@ -25,7 +25,6 @@ static bool useDebug = false;
static log_info logInfo;
static struct timespec startupTime;
static uid_t owner;
-static bool useCow = false;
static int reply_buf_limited( fuse_req_t req, const char *buf, size_t bufsize, off_t off, size_t maxsize );
static void fillStatsFile( fuse_req_t req, size_t size, off_t offset );
static void image_destroy( void *private_data );
@@ -214,15 +213,11 @@ 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) );
- request->buffer = malloc(size);
+ dnbd3_async_t *request = malloc( sizeof(dnbd3_async_t) + size );
request->length = (uint32_t)size;
request->offset = offset;
request->fuse_req = req;
- request->cow = NULL;
- request->cow_write = NULL;
-
if ( !connection_read( request ) ) {
fuse_reply_err( req, EIO );
free( request );
@@ -361,6 +356,7 @@ static void printUsage( char *argv0, int exitCode )
printf( " -S --sticky Use only servers from command line (no learning from servers)\n" );
printf( " -s Single threaded mode\n" );
printf( " -c <path> Enables cow, creates the cow files at given path\n" );
+ printf( " -L <path> Loads the cow files from a given path\n" );
exit( exitCode );
}
@@ -375,7 +371,8 @@ static const struct option longOpts[] = {
{ "rid", required_argument, NULL, 'r' },
{ "sticky", no_argument, NULL, 'S' },
{ "version", no_argument, NULL, 'v' },
- { "cow", required_argument, NULL, 'v' },
+ { "cow", required_argument, NULL, 'c' },
+ { "loadcow", required_argument, NULL, 'L' },
{ 0, 0, 0, 0 }
};
diff --git a/src/fuse/main.h b/src/fuse/main.h
index 117b31f..d444cea 100644
--- a/src/fuse/main.h
+++ b/src/fuse/main.h
@@ -1,12 +1,14 @@
#ifndef _MAIN_H_
#define _MAIN_H_
+
+#include "cowfile.h"
#include "connection.h"
#include "helper.h"
#include <dnbd3/version.h>
#include <dnbd3/build.h>
#include <dnbd3/shared/protocol.h>
#include <dnbd3/shared/log.h>
-#include "cowfile.h"
+
#define FUSE_USE_VERSION 30
#include <dnbd3/config.h>
@@ -31,6 +33,7 @@
#define INO_STATS (2)
#define INO_IMAGE (3)
+extern bool useCow;
void image_ll_getattr( fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi );
#endif /* main_H_ */ \ No newline at end of file