summaryrefslogtreecommitdiffstats
path: root/src/fuse/cowMerger/src/merger.c
blob: 3f3e43d5cd797a9ab7fc9040c050f56940b04277 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "merger.h"
#include <inttypes.h>
#define TestBit(A,k)    ( A[(k/32)] & (1 << (k%32)) )
int fhImage;
int fhCow;
off_t *filePointers;
uint64_t imageBlockCount;
uint64_t size;

bool merger( char *imageFilePath, char *cowFilePath )
{
	if( !loadFiles( imageFilePath, cowFilePath ) ) {
		return false;
	}
	if ( merge() ) {
		printf("File Merged");
		return true;
	}
	return false;
}

bool loadFiles(char *imageFilePath, char *cowFilePath)
{
	if ( ( fhImage = open ( imageFilePath, O_RDWR ) ) == -1 ) {
				printf( "Could not open Image.\n" );
				return false;
	}
	if ( ( fhCow = open ( cowFilePath, O_RDONLY ) ) == -1 ) {
				printf( "Could not open Cow File.\n" );
				close( fhImage );
				return false;
	}
	cow_metadata metadata;
	read( fhCow, &metadata, sizeof( cow_metadata ) );
	fixup_cow_metadata( metadata );
	char *buffer = malloc(sizeof(char) * ( metadata.nameLenght + 1 ) );
	read( fhCow, buffer, metadata.nameLenght * sizeof( char ) );
	size = metadata.imageSize;
	printf( "Version: %u\n",metadata.version );
	printf( "Länge: %i \n", metadata.nameLenght );
	printf( "Image Name: %s\n", buffer );
	printf( "Size: %"PRIu64"\n", size );
	printf( "pageSize: %i\n", metadata.pageSize );
	free( buffer );
	//TODO Image Validation
	imageBlockCount = ( size + (4096*256)-1 ) / (4096*256);
	off_t mmapStart = lseek( fhCow, 0L, SEEK_CUR );
	int maxPageSize = 8192;
	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 ) {
		printf("Error creating mmap in COW File.\n%s\nBye.\n ", strerror(errno) );
		close( fhCow );
		close( fhImage );
		return false;
	}
	return true;
}

bool merge()
{
	uint64_t mergedBlocks = 0;
	for( uint64_t i = 0; i < imageBlockCount; i++ ) {
		printf( "Merged %"PRIu64" of %"PRIu64" Blocks \n", i, imageBlockCount );
		off_t pointer = (off_t) filePointers[i];
		if( pointer != 0) {
			int blockState[8];
			lseek( fhCow, filePointers[i], SEEK_SET );
			read( fhCow, &blockState, sizeof(int) * 8 );
			for( int j = 0; j < 256; j++ ) {
				if( TestBit( blockState, j ) ) {
					lseek( fhCow, ((off_t) filePointers[i] + ( 4096 * ( j + 1) ) ), SEEK_SET );
					char buff[4096] = {0};
					if( read(fhCow, &buff, 4096) < 0) {
						 printf("Error on reading Cow File."
								 " BigBlock: %"PRIu64"n", i );
						 return false;
					}
					lseek( fhImage, ( i * 4096 * 256) + ( 4096 * j ), SEEK_SET );
					if( write( fhImage, &buff, 4096 ) < 0) {
						 printf("Error on writing to File."
								 " BigBlock: %"PRIu64"\n", i );
						 return false;
					}
					mergedBlocks++;
				}
			}
		}
	}
	printf( "Merged %"PRIu64" Blocks\n", mergedBlocks );
	ftruncate( fhImage, size);
	return true;
}