summaryrefslogtreecommitdiffstats
path: root/src/fuse/cowfile.h
diff options
context:
space:
mode:
authorSimon Rettberg2023-03-29 12:03:54 +0200
committerSimon Rettberg2024-05-13 18:26:42 +0200
commitec0b9b5f72607335ac19d4ea00c24919943b7970 (patch)
treefaf735a62dff9d88f22c1073b601e5af913cc3e9 /src/fuse/cowfile.h
parent[FUSE] Fixed cow daemon issue (diff)
downloaddnbd3-ec0b9b5f72607335ac19d4ea00c24919943b7970.tar.gz
dnbd3-ec0b9b5f72607335ac19d4ea00c24919943b7970.tar.xz
dnbd3-ec0b9b5f72607335ac19d4ea00c24919943b7970.zip
[FUSE] cow: Cleanup, comments, fixes, minor refactoring
- Use the term "cluster" for a group of dnbd3-blocks instead of also calling them blocks. - Use term "table" instead of "array" for the L1 and L2 tables. - Use term "index" instead of "offset" when addressing those tables - Fix a few logic bugs, use-after-free - Add TODOs for parts that need better comments
Diffstat (limited to 'src/fuse/cowfile.h')
-rw-r--r--src/fuse/cowfile.h93
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_ */