diff options
-rw-r--r-- | src/fuse/cow.c | 115 | ||||
-rw-r--r-- | src/fuse/cow.h | 9 | ||||
-rw-r--r-- | src/fuse/cowMerger/src/merger.c | 2 | ||||
-rwxr-xr-x | src/fuse/main.c | 37 |
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
|