diff options
Diffstat (limited to 'src/fuse/cow.c')
-rw-r--r-- | src/fuse/cow.c | 115 |
1 files changed, 62 insertions, 53 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; |