summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Scherle2018-12-02 18:48:31 +0100
committerMichael Scherle2018-12-02 18:48:31 +0100
commitd4fa4a9b64a78f082a1b135efbe53952d7317346 (patch)
tree446c3f0b7514e1a9a4f1e470403a911db0c5ab8a
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.
-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