diff options
Diffstat (limited to 'src/fuse/cowfile.h')
-rw-r--r-- | src/fuse/cowfile.h | 93 |
1 files changed, 49 insertions, 44 deletions
diff --git a/src/fuse/cowfile.h b/src/fuse/cowfile.h index d91d122..a07469d 100644 --- a/src/fuse/cowfile.h +++ b/src/fuse/cowfile.h @@ -1,23 +1,20 @@ #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" +#include <dnbd3/config/cow.h> +#include <stdint.h> +#include <stdbool.h> +#include <stdatomic.h> +#include <stdlib.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 ) ) ) +// Net storage capacity of a single cluster in the data file +#define COW_DATA_CLUSTER_SIZE ( COW_BITFIELD_SIZE * 8 * DNBD3_BLOCK_SIZE ) +// Number of entries per L2 table +#define COW_L2_TABLE_SIZE 1024 +// Net storage capacity in data file represented by a full L2 table +#define COW_FULL_L2_TABLE_DATA_SIZE ( COW_L2_TABLE_SIZE * COW_DATA_CLUSTER_SIZE ) _Static_assert( ATOMIC_INT_LOCK_FREE == 2, "ATOMIC INT not lock free" ); _Static_assert( ATOMIC_LONG_LOCK_FREE == 2, "ATOMIC LONG not lock free" ); @@ -39,7 +36,7 @@ typedef struct cowfile_metadata_header atomic_uint_least64_t imageSize; // 8byte int32_t version; // 4byte int32_t blocksize; // 4byte - uint64_t originalImageSize; // 8byte + uint64_t originalImageSize; // 8byte - the name implies this is the size of the image on the server, but apparently it changes if we truncate the image etc. better name? uint64_t metaDataStart; // 8byte int32_t bitfieldSize; // 4byte int32_t nextL2; // 4byte @@ -53,54 +50,62 @@ typedef struct cowfile_metadata_header _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 +#define COW_L2_ENTRY_SIZE 64 +typedef struct cow_l2_entry { 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" ); - - + atomic_char bitfield[COW_BITFIELD_SIZE]; +} cow_l2_entry_t; +_Static_assert( sizeof( cow_l2_entry_t ) == COW_L2_ENTRY_SIZE, "cow_l2_entry_t is messed up" ); + +/** + * Open request for reading/writing the virtual image we expose. + * TODO Please verify field comments + */ 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; + size_t fuseRequestSize; // Number of bytes to be read/written + off_t fuseRequestOffset; // Absolute offset into the image, as seen by user space + char *readBuffer; // Used only in read case? + const char *writeBuffer; // Used only in write case? + atomic_size_t bytesWorkedOn; // Used for ??? + atomic_int workCounter; // How many pending sub requests (see below) + atomic_int errorCode; // For reporting back to fuse + fuse_ino_t ino; // Inode of file, used for ??? + struct fuse_file_info *fi; // Used for ??? } cow_request_t; typedef struct cow_sub_request cow_sub_request_t; typedef void ( *cow_callback )( cow_sub_request_t *sRequest ); +/** + * A sub-request for above, which needs to be completed successfully + * before the parent cow_request can be completed. + * TODO Please verify field comments + */ 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[]; + size_t size; // size of this sub-request + off_t inClusterOffset; // offset relative to!? cow-block? DNBD3 block? cluster? + const char *writeSrc; // ??? + char *buffer; // ??? + cow_l2_entry_t *block; // the cluster inClusterOffset refers to + cow_callback callback; // Callback when we're done handling this + cow_request_t *cowRequest; // parent request + dnbd3_async_t dRequest; // Probably request to dnbd3-server for non-aligned writes (wrt 4k dnbd3 block) + char writeBuffer[]; // ??? } cow_sub_request_t; typedef struct cow_curl_read_upload { atomic_uint_least64_t time; - cow_block_metadata_t *block; + cow_l2_entry_t *block; size_t position; long unsigned int blocknumber; int fails; - curl_off_t ulLast; + int64_t ulLast; } cow_curl_read_upload_t; @@ -112,7 +117,7 @@ typedef struct cow_block_upload_statistics typedef int32_t l1; -typedef cow_block_metadata_t l2[COW_L2_SIZE]; +typedef cow_l2_entry_t l2[COW_L2_TABLE_SIZE]; bool cowfile_init( char *path, const char *image_Name, uint16_t imageVersion, atomic_uint_fast64_t **imageSizePtr, char *serverAddress, bool sStdout, bool sFile ); @@ -133,4 +138,4 @@ int cow_printStats( char *buffer, const size_t len ); void cowfile_close(); -#endif /* COWFILE_H_ */
\ No newline at end of file +#endif /* COWFILE_H_ */ |