summaryrefslogtreecommitdiffstats
path: root/src/fuse/cowMerger/src/merger.c
blob: 17926f775091f314b7a6af2df83d90d76f369404 (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
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "merger.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;
	}
	unsigned int version ;

	read(fhCow,&version,sizeof(unsigned int));
	read(fhCow,&size,sizeof(uint64_t));
	int l;
	read(fhCow,&l,sizeof(int));

	char *buffer = malloc(sizeof(char)*(l+1));
	read(fhCow,buffer,l*sizeof(char));
	buffer[l]='\0';

	int pageSize;
	read(fhCow,&pageSize,sizeof(int));
	printf("Version: %u\n",version);
	printf("länge: %i \n",l);
	printf("Image Name: %s\n",buffer);
	printf("Size: %ld\n", (long)size);
	printf("pageSize: %i\n", (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;
	filePointers = mmap(NULL,imageBlockCount*sizeof(off_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 %llu of %llu 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,filePointers[i]+(4096*(j+1)),SEEK_SET);
					char buff[4096] = {0};
					if(read(fhCow, &buff, 4096) < 0){
						 printf("Error on reading Cow File. BigBlock: %llu\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: %llu\n",i);
						 return false;
					}

				}
			}
			mergedBlocks++;
		}
	}
	printf("Merged %llu Blocks\n",mergedBlocks);
	ftruncate(fhImage, size);
	return true;
}