summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fuse/cow.c115
-rw-r--r--src/fuse/cow.h9
-rw-r--r--src/fuse/cowMerger/src/merger.c2
-rwxr-xr-xsrc/fuse/main.c37
4 files changed, 81 insertions, 82 deletions
diff --git a/src/fuse/cow.c b/src/fuse/cow.c
index bd61704..c9966d1 100644
--- a/src/fuse/cow.c
+++ b/src/fuse/cow.c
@@ -14,10 +14,9 @@
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
-#include <unistd.h>
#include <pthread.h>
#include <inttypes.h>
-
+#include "../shared/log.h"
#define ClearBit(A,k) ( A[(k/32)] &= ~(1 << (k%32)) )
@@ -27,7 +26,6 @@ const unsigned int version = 1;
int fh;
uint64_t MaxImageSizeInBytes = 1099511627776; //1 Tebibyte in byte
off_t *filePointers;
-uint64_t imageSubBlockCount;
size_t imageBlockCount;
bool debug = true;
uint64_t remoteImageSize;
@@ -119,7 +117,7 @@ static cow_request* removeCowRequest(cow_requests_queue queue,cow_request *reque
}
-void writeImageSizeToFile(uint64_t size)
+void cow_writeImageSizeToFile(uint64_t size)
{
if(debug) {
printf("ImageSize Changed to %"PRIu64"\n", size);
@@ -129,12 +127,21 @@ void writeImageSizeToFile(uint64_t size)
pwrite( fh, &metadata, sizeof(cow_metadata), 0 );
}
+uint64_t cow_init(char *cow_path, char *image_Name, uint64_t imageSize, bool overWrite){
+ if( access( cow_path, F_OK ) != -1 && !overWrite ) {
+ return loadFile( cow_path, image_Name, imageSize );
+ } else {
+ return createFile( cow_path, image_Name, imageSize );
+ }
+}
+
-bool cow_createFile(char *cow_path, char *image_Name, uint64_t imageSize)
+
+uint64_t createFile(char *cow_path, char *image_Name, uint64_t imageSize)
{
- remoteImageSize = (size_t) imageSize;
+ remoteImageSize = imageSize;
if(( fh = open (cow_path, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR) ) == -1 ){
- puts( "Could not create COW File. Bye.\n" );
+ logadd( LOG_ERROR, "Could not create COW File. Bye.\n" );
return false;
}
@@ -157,7 +164,7 @@ bool cow_createFile(char *cow_path, char *image_Name, uint64_t imageSize)
if(filePointers == MAP_FAILED ){
close( fh );
printf( "Error creating mmap in COW File.\n%s\nBye.\n ", strerror( errno ) );
- return false;
+ return 0;
}
@@ -178,38 +185,42 @@ bool cow_createFile(char *cow_path, char *image_Name, uint64_t imageSize)
if( pthread_spin_init( &requestsQueueLock, PTHREAD_PROCESS_PRIVATE ) != 0 ){
printf( "Spinlock init failure" );
}
- return true;
+ return imageSize;
}
-uint64_t cow_loadFile( char *cow_path, uint64_t imageSize )
+uint64_t loadFile( char *cow_path, char *image_Name, uint64_t imageSize )
{
- remoteImageSize = ( size_t ) imageSize;
+ remoteImageSize = imageSize;
if(( fh = open (cow_path, O_RDWR, S_IRUSR|S_IWUSR)) == -1 ){
- printf( "Could not open Cow File.\n" );
+ logadd( LOG_ERROR, "Could not load COW File. Bye.\n" );
return false;
}
read( fh, &metadata, sizeof( cow_metadata ) );
fixup_cow_metadata( metadata );
- char *buffer = malloc(sizeof(char) * ( metadata.nameLenght + 1 ) );
- read( fh, buffer, metadata.nameLenght * sizeof( char ) );
+ char *imageName = malloc(sizeof(char) * ( metadata.nameLenght + 1 ) );
+ read( fh, imageName, metadata.nameLenght * sizeof( char ) );
off_t mmapStart = lseek( fh, 0L, SEEK_CUR );
int maxPageSize = 8192;
- mmapStart = ( ( mmapStart + maxPageSize - 1) / maxPageSize) * maxPageSize;
+ mmapStart = ( ( mmapStart + maxPageSize - 1) / maxPageSize ) * maxPageSize;
if( debug ){
printf( "Version: %u\n", metadata.version );
printf( "länge: %i \n", metadata.nameLenght);
- printf( "Image Name: %s\n", buffer );
+ printf( "Image Name: %s\n", imageName );
printf( "Size: %ld\n", (long) metadata.imageSize );
printf( "pageSize: %i\n", metadata.pageSize );
printf( "mmap start: %"PRIu64"\n", mmapStart );
}
- free( buffer );
+ if( strcmp( image_Name, imageName ) != 0 ) {
+ logadd( LOG_ERROR, "Wrong COW File for this Image.\n" );
+ return 0;
+ }
+ free( imageName );
imageBlockCount = ( MaxImageSizeInBytes / (1024 * 1024) );
- filePointers = mmap( NULL, imageBlockCount * sizeof( uint64_t ), PROT_READ, MAP_SHARED, fh, mmapStart );
+ filePointers = mmap( NULL, imageBlockCount * sizeof( uint64_t ), PROT_READ | PROT_WRITE, MAP_SHARED, fh, mmapStart );
if( filePointers == MAP_FAILED ){
- printf( "Error creating mmap in COW File.\n%s\nBye.\n ", strerror( errno ) );
+ printf( "Error creating mmap in COW File.\n%s\nBye.\n", strerror( errno ) );
close( fh );
return 0;
}
@@ -217,7 +228,9 @@ uint64_t cow_loadFile( char *cow_path, uint64_t imageSize )
if( pthread_spin_init( &requestsQueueLock, PTHREAD_PROCESS_PRIVATE ) != 0 ){
printf( "Spinlock init failure" );
}
- return metadata.imageSize ;
+ uint64_t imageSizeCow = metadata.imageSize;
+ fixup_cow_metadata( metadata );
+ return imageSizeCow ;
}
bool createBigBlock(unsigned long id)
@@ -228,10 +241,7 @@ bool createBigBlock(unsigned long id)
filePointers[id] = (uint64_t) blockStart;
// go to next Page size
int blockState[8] = {0};
- /*
- if( debug ){
- printf("Creating BigBlock: %lu offset: %"PRIu64"\n", id, blockStart);
- }*/
+
pwrite( fh, &blockState, sizeof( int ) * 8, blockStart);
// go to next Page size
@@ -346,7 +356,7 @@ void closeAcccess(cow_request *request)
pthread_spin_unlock(&requestsQueueLock);
}
-int writeCow(const char *data, size_t size, off_t offset)
+int cow_write(const char *data, size_t size, off_t offset)
{
int writtenBytes = 0;
size_t sizeToBigBlock = 0;
@@ -359,8 +369,6 @@ int writeCow(const char *data, size_t size, off_t offset)
bigBlockStart = ( bigBlockId * ( 4096 * 256 ) );
bigBlockOffset =( offset + writtenBytes )- bigBlockStart;
// how much i can write in this block
- //TODO CHECK THIS
- //sizeToBigBlock = 4096*256 - (bigBlockOffset -bigBlockStart);
sizeToBigBlock = 4096 * 256 - bigBlockOffset;
if( ( size - writtenBytes ) < sizeToBigBlock ) {
sizeToBigBlock = size - writtenBytes;
@@ -369,6 +377,7 @@ int writeCow(const char *data, size_t size, off_t offset)
bigBlockId++;
}
///////////////////////////////
+ /*
if( debug ){
char *tmp = malloc( size );
cow_read( tmp, size, offset );
@@ -380,7 +389,7 @@ int writeCow(const char *data, size_t size, off_t offset)
}
free(tmp);
}
-
+ */
///////////////////////////////
closeAcccess( &request );
return writtenBytes;
@@ -409,14 +418,9 @@ int writeToBigBlock(unsigned long bigBlockId, const char *data, off_t offset,siz
if( ( offset % 4096 != 0 ) && ( !TestBit( blockState, firstSmallBlock ) ) ) {
size_t sizeToPrepend = offset % 4096;
- //lseek( fh, filePointers[bigBlockId] + 4096 + offset - sizeToPrepend, SEEK_SET );
char *startData = calloc(sizeToPrepend,1);
off_t offsetToPrepend = offset + ( bigBlockId * ( 4096 * 256 ) ) - sizeToPrepend;
- // TODO CHECK THIS
- //offsetToPrepend = offsetToPrepend - (offsetToPrepend % 4096);
-
-
if( ( ( ( uint64_t ) offsetToPrepend ) + ( ( uint64_t ) sizeToPrepend) ) > remoteImageSize ) {
sizeToPrepend = remoteImageSize-offsetToPrepend;
}
@@ -440,7 +444,6 @@ int writeToBigBlock(unsigned long bigBlockId, const char *data, off_t offset,siz
if( ( ( offset + size ) % 4096 != 0 ) && ( !TestBit( blockState, lastSmallBlock ) ) ) {
size_t sizeToAppend= 4096 - ( ( ( ( size_t ) offset ) + size ) % 4096 );
- //TODO TEST -1?
off_t offsetToAppend = bigBlockId * 256 * 4096 +( ( off_t ) offset ) + size;
char *startData = calloc( sizeToAppend, 1 );
@@ -451,7 +454,6 @@ int writeToBigBlock(unsigned long bigBlockId, const char *data, off_t offset,siz
if( ( ( size_t ) offsetToAppend) < remoteImageSize ) {
imageReadInternal( startData, sizeToAppend, offsetToAppend );
}
- //lseek(fh,filePointers[bigBlockId]+4096+offset,SEEK_SET);
pwrite( fh, startData, ( 4096 -( ( ( ( size_t ) offset ) + size ) % 4096 ) ), ( (off_t) filePointers[bigBlockId] + 4096 + offset + size ) );
free( startData );
@@ -475,20 +477,18 @@ int getSmallBlockId(off_t offset)
int cow_read(char *buf, size_t size, off_t offset)
{
unsigned long bigBlockStartId = offset / ( 4096 * 256 );
- //TODO CHECK THIS
unsigned long bigBlockEndId = ( offset + size - 1) / ( 4096 * 256 );
unsigned long bigBlockId = bigBlockStartId;
cow_request request = getAccess( offset, size );
size_t bigBlockStart = ( bigBlockId * ( 4096 * 256 ) );
size_t bigBlockOffset = offset- bigBlockStart;
- // how much i can write from this block
- //TODO IS THIS RIGHT?
+ // how much i can read from this block
size_t sizeToBigBlock = ( ( 4096 * 256 ) - bigBlockOffset );
if( sizeToBigBlock > size) {
sizeToBigBlock = size;
}
- int bytesRead = readBigBlock( bigBlockStartId, buf,sizeToBigBlock, bigBlockOffset );
+ int bytesRead = readBigBlock( bigBlockStartId, buf, sizeToBigBlock, bigBlockOffset );
if( bigBlockStartId != bigBlockEndId && ( size - sizeToBigBlock ) > 0 ) {
bytesRead += readBigBlock( bigBlockEndId, buf + sizeToBigBlock, ( size - sizeToBigBlock ), 0 );
@@ -508,15 +508,12 @@ int readBigBlock(long bigBlockId, char *buf, size_t size, off_t offset)
pread( fh, &blockState, sizeof( int ) * 8, ( (off_t) filePointers[bigBlockId] ));
int block = getSmallBlockId( offset );
int endBlock = getSmallBlockId( offset + size - 1 );
- int startBlock;
- char *curBuf = buf;
size_t readBytes = 0;
while( readBytes < size ) {
- startBlock = block;
if( !TestBit( blockState, block ) ) {
- while( !TestBit( blockState, block ) && block!= endBlock ) {
+ while( !TestBit( blockState, block ) && block != endBlock ) {
block++;
if( block > 255 ) {
printf( "ERROR SmallBlack id > 255" );
@@ -537,17 +534,21 @@ int readBigBlock(long bigBlockId, char *buf, size_t size, off_t offset)
}
startOffset = startOffset + ( bigBlockId * 4096 * 256 );
+
if( sizeToRemoteRead > 0 ) {
- readBytes += imageReadInternal( curBuf, sizeToRemoteRead, startOffset );
+ readBytes += imageReadInternal( (buf + readBytes), sizeToRemoteRead, startOffset );
}
-
+ /*
+ char str[sizeToRemoteRead];
+ readBytes += imageReadInternal( str, sizeToRemoteRead, startOffset );
+ memcpy( buf + readBytes, str, sizeToRemoteRead );
+ */
if( readBytes < sizeToRead ) {
for( int i = ( ( int )readBytes ); readBytes < sizeToRead; i++ ) {
- curBuf[i] = 0;
+ buf[i] = 0;
readBytes++;
}
}
- curBuf += sizeToRead;
} else {
while( TestBit( blockState, block ) && block != endBlock) {
block++;
@@ -555,17 +556,25 @@ int readBigBlock(long bigBlockId, char *buf, size_t size, off_t offset)
printf( "ERROR SmallBlack id > 255" );
}
}
-
-
- off_t startOffset = offset+readBytes;
-
+ off_t startOffset = offset + readBytes;
size_t sizeToRead = ( ( block + 1 ) * 4096) - startOffset;
if( sizeToRead > size - readBytes ) {
sizeToRead = size - readBytes;
}
//read Data local
- readBytes += pread(fh, curBuf, sizeToRead, ( (off_t) filePointers[bigBlockId] + 4096 + startOffset ) );
- curBuf += readBytes;
+
+ size_t singleReadBytes = pread(fh, (buf + readBytes), sizeToRead, ( (off_t) filePointers[bigBlockId] + 4096 + startOffset ) );
+
+
+ /*
+ char str[sizeToRead];
+ size_t singleReadBytes = pread(fh, str, sizeToRead, ( (off_t) filePointers[bigBlockId] + 4096 + startOffset ) );
+ memcpy( buf + readBytes, str, sizeToRead);
+ */
+ if (singleReadBytes < sizeToRead) {
+ printf("Error on reading data from COW File. File end reached?");
+ }
+ readBytes += singleReadBytes;
}
}
return (int) readBytes;
diff --git a/src/fuse/cow.h b/src/fuse/cow.h
index 7f2c6bb..78cc3ef 100644
--- a/src/fuse/cow.h
+++ b/src/fuse/cow.h
@@ -31,12 +31,13 @@ typedef struct {
uint32_t pageSize;
} cow_metadata;
-
-bool cow_createFile(char *cow_path, char *image_Name,uint64_t imageSize);
+uint64_t cow_init(char *cow_path, char *image_Name, uint64_t imageSize, bool overWrite);
+uint64_t createFile(char *cow_path, char *image_Name,uint64_t imageSize);
bool createBigBlock(unsigned long id);
int cow_read(char *buf, size_t size, off_t offset);
-uint64_t cow_loadFile( char *cow_path, uint64_t imageSize );
-
+int cow_write(const char *data, size_t size, off_t offset);
+uint64_t loadFile( char *cow_path,char *image_Name, uint64_t imageSize );
+void cow_writeImageSizeToFile(uint64_t size);
int readBigBlock(long bigBlockId ,char *buf,size_t size, off_t offset);
void onClose();
cow_request getAccess(off_t offset,size_t size);
diff --git a/src/fuse/cowMerger/src/merger.c b/src/fuse/cowMerger/src/merger.c
index 3f4aa89..3f3e43d 100644
--- a/src/fuse/cowMerger/src/merger.c
+++ b/src/fuse/cowMerger/src/merger.c
@@ -49,7 +49,7 @@ bool loadFiles(char *imageFilePath, char *cowFilePath)
mmapStart = ( ( mmapStart + maxPageSize - 1) / maxPageSize ) * maxPageSize;
printf( "mmapStart: %"PRIu64"\n", mmapStart );
filePointers = mmap( NULL, imageBlockCount * sizeof(uint64_t), PROT_READ, MAP_SHARED, fhCow, mmapStart);
- if(filePointers == MAP_FAILED ){
+ if(filePointers == MAP_FAILED ) {
printf("Error creating mmap in COW File.\n%s\nBye.\n ", strerror(errno) );
close( fhCow );
close( fhImage );
diff --git a/src/fuse/main.c b/src/fuse/main.c
index ee52695..89e1695 100755
--- a/src/fuse/main.c
+++ b/src/fuse/main.c
@@ -156,17 +156,16 @@ static int fillStatsFile(char *buf, size_t size, off_t offset) {
memcpy( buf, buffer + offset, len );
return len;
}
-
-static int image_write(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi UNUSED)
+static int image_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi UNUSED)
{
if ( path[1] == STATS_PATH[1] ) {
return -EIO;
}
if( ( ( ( size_t ) offset ) + size ) > imageSize ){
imageSize = ( ( size_t ) offset ) + size;
- writeImageSizeToFile( imageSize );
+ cow_writeImageSizeToFile( imageSize );
}
- return writeCow(buf,size, offset);
+ return cow_write(buf,size, offset);
}
int imageReadInternal(char *buf,size_t size, off_t offset){
dnbd3_async_t request;
@@ -279,10 +278,10 @@ static void image_destroy(void *private_data UNUSED)
}
-static int image_truncate(const char *path, off_t size, struct fuse_file_info *fi UNUSED) {
+static int image_truncate(const char *path, off_t size) {
if ( strcmp( path, IMAGE_PATH ) == 0 ) {
- imageSize=size;
- writeImageSizeToFile((uint64_t)size);
+ imageSize = size;
+ cow_writeImageSizeToFile((uint64_t)size);
return 0;
}
return -1;
@@ -345,7 +344,7 @@ static void printUsage(char *argv0, int exitCode)
printf( " -l --log Write log to given location\n" );
printf( " -o --option Mount options to pass to libfuse\n" );
printf( " -d --debug Don't fork and print debug output (fuse > stderr, dnbd3 > stdout)\n" );
- printf( " -c --cow Path where the cow file should be created");
+ printf( " -c --cow Path where the cow file should be created. Use -z to overwrite existing cow files.\n");
fuse_main( 2, arg, &dnbd3_fuse_no_operations, NULL );
exit( exitCode );
}
@@ -374,7 +373,7 @@ int main(int argc, char *argv[])
int newArgc;
int opt, lidx;
bool testOpt = false;
- bool loadCow = false;
+ bool overWrite = false;
if ( argc <= 1 || strcmp( argv[1], "--help" ) == 0 || strcmp( argv[1], "--usage" ) == 0 ) {
printUsage( argv[0], 0 );
@@ -443,7 +442,7 @@ int main(int argc, char *argv[])
useCow=true;
break;
case 'z':
- loadCow = true;
+ overWrite = true;
break;
default:
printUsage( argv[0], EXIT_FAILURE );
@@ -487,21 +486,11 @@ int main(int argc, char *argv[])
}
if(useCow){
printf("Using Cow");
- if(loadCow){
- printf("Loading Cow");
- uint64_t cowSize = cow_loadFile(cow_path, imageSize);
-
- if(cowSize == 0){
- logadd( LOG_ERROR, "Could not load COW FIle. Bye.\n" );
- return EXIT_FAILURE;
- } else{
- imageSize = cowSize;
- }
+ uint64_t cowSize = cow_init(cow_path, image_Name, imageSize,overWrite);
+ if(cowSize == 0){
+ return EXIT_FAILURE;
} else {
- if(!cow_createFile(cow_path, image_Name, imageSize)){
- logadd( LOG_ERROR, "Could not create COW FIle. Bye.\n" );
- return EXIT_FAILURE;
- }
+ imageSize = cowSize;
}
}
// Since dnbd3 is always read only and the remote image will not change