diff options
Diffstat (limited to 'src/fuse/cowfile.h')
-rw-r--r-- | src/fuse/cowfile.h | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/src/fuse/cowfile.h b/src/fuse/cowfile.h new file mode 100644 index 0000000..c74ab99 --- /dev/null +++ b/src/fuse/cowfile.h @@ -0,0 +1,136 @@ +#ifndef _COWFILE_H_ +#define _COWFILE_H_ + +#include <stdint.h> +#include <stdlib.h> +#include <stdatomic.h> +#include <dnbd3/shared/log.h> +#include <sys/mman.h> +#include <string.h> +#include <pthread.h> +#include <errno.h> +#include <curl/curl.h> +#include "main.h" +#include "connection.h" + + +#define COW_METADATA_STORAGE_CAPACITY ( COW_BITFIELD_SIZE * 8 * DNBD3_BLOCK_SIZE ) +#define COW_L2_SIZE 1024 +#define COW_L2_STORAGE_CAPACITY ( COW_L2_SIZE * COW_METADATA_STORAGE_CAPACITY ) +#define container_of( ptr, type, member ) ( (type *)( (char *)( ptr ) - (char *)&( ( (type *)NULL )->member ) ) ) + +_Static_assert( ATOMIC_INT_LOCK_FREE == 2, "ATOMIC INT not lock free" ); +_Static_assert( ATOMIC_LONG_LOCK_FREE == 2, "ATOMIC LONG not lock free" ); +_Static_assert( ATOMIC_LLONG_LOCK_FREE == 2, "ATOMIC LLONG not lock free" ); +_Static_assert( sizeof( atomic_uint_least64_t ) == 8, "atomic_uint_least64_t not 8 byte" ); +_Static_assert( sizeof( atomic_int_least64_t ) == 8, "atomic_int_least64_t not 8 byte" ); + +enum dataSource +{ + local, + remote, + zero +}; + +#define COW_METADATA_HEADER_SIZE 320 +typedef struct cowfile_metadata_header +{ + uint64_t magicValue; // 8byte + atomic_uint_least64_t imageSize; // 8byte + int32_t version; // 4byte + int32_t blocksize; // 4byte + uint64_t originalImageSize; // 8byte + uint64_t metaDataStart; // 8byte + int32_t bitfieldSize; // 4byte + int32_t nextL2; // 4byte + atomic_uint_least64_t metadataFileSize; // 8byte + atomic_uint_least64_t dataFileSize; // 8byte + uint64_t maxImageSize; // 8byte + uint64_t creationTime; // 8byte + char uuid[40]; // 40byte + char imageName[200]; // 200byte +} cowfile_metadata_header_t; +_Static_assert( + sizeof( cowfile_metadata_header_t ) == COW_METADATA_HEADER_SIZE, "cowfile_metadata_header is messed up" ); + +#define COW_METADATA_METADATA_SIZE 64 +typedef struct cow_block_metadata +{ + atomic_int_least64_t offset; + atomic_uint_least64_t timeChanged; + atomic_uint_least64_t uploads; + atomic_char bitfield[40]; +} cow_block_metadata_t; +_Static_assert( sizeof( cow_block_metadata_t ) == COW_METADATA_METADATA_SIZE, "cow_block_metadata_t is messed up" ); + + +typedef struct cow_request +{ + size_t fuseRequestSize; + off_t fuseRequestOffset; + char *readBuffer; + const char *writeBuffer; + atomic_size_t bytesWorkedOn; + atomic_int workCounter; + atomic_int errorCode; + fuse_ino_t ino; + struct fuse_file_info *fi; +} cow_request_t; + +typedef struct cow_sub_request cow_sub_request_t; +typedef void ( *cow_callback )( cow_sub_request_t *sRequest ); + +typedef struct cow_sub_request +{ + size_t size; + off_t inBlockOffset; + 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 +{ + atomic_uint_least64_t time; + cow_block_metadata_t *block; + size_t position; + long unsigned int blocknumber; + int fails; + curl_off_t ulLast; +} cow_curl_read_upload_t; + + +typedef struct cow_block_upload_statistics +{ + uint64_t blocknumber; + uint64_t uploads; +} cow_block_upload_statistics_t; + + +typedef int32_t l1; +typedef cow_block_metadata_t l2[COW_L2_SIZE]; + +bool cowfile_init( char *path, const char *image_Name, uint16_t imageVersion, atomic_uint_fast64_t **imageSizePtr, + char *serverAddress, bool sStdout, bool sFile ); + +bool cowfile_load( char *path, atomic_uint_fast64_t **imageSizePtr, char *serverAddress, bool sStdout, bool sFile ); + +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 ); + +void cowfile_handleCallback( dnbd3_async_t *request ); + +void cowfile_setSize( fuse_req_t req, size_t size, fuse_ino_t ino, struct fuse_file_info *fi ); + +void readRemoteData( cow_sub_request_t *sRequest ); + +int cow_printStats( char *buffer, const size_t len ); + +void cowfile_close(); + +#endif /* COWFILE_H_ */
\ No newline at end of file |