summaryrefslogtreecommitdiffstats
path: root/src/fuse/cow.c
diff options
context:
space:
mode:
authorMichael Scherle2018-12-02 18:48:31 +0100
committerMichael Scherle2018-12-02 18:48:31 +0100
commitd4fa4a9b64a78f082a1b135efbe53952d7317346 (patch)
tree446c3f0b7514e1a9a4f1e470403a911db0c5ab8a /src/fuse/cow.c
parentcleaned up code and added improvements (diff)
downloaddnbd3-d4fa4a9b64a78f082a1b135efbe53952d7317346.tar.gz
dnbd3-d4fa4a9b64a78f082a1b135efbe53952d7317346.tar.xz
dnbd3-d4fa4a9b64a78f082a1b135efbe53952d7317346.zip
changed standart behavior to not overwrite cow file
- in standart cow modus, if an cow file exists it will try to load it, if the given cow file doesn't match with the given image it will exit with an error. - added -z parameter to force an cow file overwrite.
Diffstat (limited to 'src/fuse/cow.c')
-rw-r--r--src/fuse/cow.c115
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;