|
|
@ -0,0 +1,565 @@ |
|
|
|
#ifndef LSFS_DISK_CONTROLLER_H |
|
|
|
#define LSFS_DISK_CONTROLLER_H |
|
|
|
|
|
|
|
#include <assert.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <stdio.h> |
|
|
|
#include <string.h> |
|
|
|
#include <stdint.h> |
|
|
|
#include <stdbool.h> |
|
|
|
#include <time.h> |
|
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
typedef struct struct_partition_control partition_control; |
|
|
|
typedef struct struct_global_tag global_tag; |
|
|
|
typedef struct struct_partition_control partition_control; |
|
|
|
typedef struct File_System_Control_Information FSCI; |
|
|
|
typedef struct meta_information_format mif; |
|
|
|
typedef struct tag_record tag_record; |
|
|
|
|
|
|
|
typedef uint64_t lsfs_sector_offset; |
|
|
|
typedef lsfs_sector_offset lsfs_file_id; |
|
|
|
typedef lsfs_sector_offset lsfs_tag_id; |
|
|
|
|
|
|
|
//typedef uint64_t sector_index; |
|
|
|
static FILE* disk; |
|
|
|
static partition_control p_control; // used for debugging |
|
|
|
|
|
|
|
int create_file_system(); |
|
|
|
lsfs_sector_offset lsfs_disk_create_tag(char* tag_name, bool is_filename); |
|
|
|
lsfs_sector_offset lsfs_disk_create_file(char* filename, lsfs_tag_id* tags, void* file_data); |
|
|
|
int lsfs_disk_untag_file(lsfs_tag_id tag_id, lsfs_file_id file_id); |
|
|
|
int lsfs_disk_tag_file(lsfs_tag_id tag_id, lsfs_file_id file_id); |
|
|
|
int lsfs_disk_delete_tag(lsfs_tag_id tag_id); |
|
|
|
int lsfs_disk_delete_file(lsfs_file_id file_id); |
|
|
|
int get_free_sectors(int num_sectors_needed, lsfs_sector_offset* output_array); |
|
|
|
int lsfs_disk_read_data_from_file(lsfs_file_id file_id, int buffer_size, void* buffer_for_data); |
|
|
|
int lsfs_disk_write_data_to_file(lsfs_file_id file_id, int data_length, char *data); |
|
|
|
int lsfs_disk_rename_tag(lsfs_file_id file_id, char* new_tagname); |
|
|
|
int lsfs_disk_rename_file(lsfs_file_id file_id, const char* new_filename); |
|
|
|
int lsfs_disk_load_disk(); |
|
|
|
int write_data_to_disk(lsfs_sector_offset at_sector, void* data_to_write); |
|
|
|
int read_data_from_disk(lsfs_sector_offset index, void* data_buffer); |
|
|
|
int write_data_to_disk_off(lsfs_sector_offset index, void* data_to_write, int offset); |
|
|
|
|
|
|
|
|
|
|
|
#define SECTOR_SIZE 4096 |
|
|
|
#define DEFAULT_FILE_SIZE 1 // This is in sectors |
|
|
|
#define DEFAULT_MASTER_TAG_TABLE_SIZE 3855 // correspond to 1 MiB in sectors 3855 * 57825 |
|
|
|
#define DEFAULT_TAG_TABLE_SIZE 64 // correspond to 262144 bytes in sectors - 16384 files pr. default. (minus one, the last is a pointer to a table more ) |
|
|
|
#define MAX_MASTER_TAGS 57825 |
|
|
|
#define MAX_TAGS_IN_TAG_TABLE 16384 |
|
|
|
#define MAX_TAGS_FOR_A_FILE 32 |
|
|
|
|
|
|
|
#define MAX_NUM_ONE_LEVEL_DATA 256 // First Mib of a file. |
|
|
|
#define MAX_NUM_TWO_LEVEL_DATA 94 // First Mib of a file. |
|
|
|
#define MAX_NUM_THREE_LEVEL_DATA 94 // First Mib of a file. |
|
|
|
|
|
|
|
typedef struct struct_partition_control{ |
|
|
|
FSCI* fsci; |
|
|
|
global_tag* master_table; |
|
|
|
} __attribute__((packed)) partition_control; |
|
|
|
|
|
|
|
typedef struct File_System_Control_Information { |
|
|
|
uint64_t offset_on_disk; |
|
|
|
uint64_t next_partition; |
|
|
|
uint64_t maximum_sectors_on_partition; |
|
|
|
uint64_t maximum_sectors_on_disk; |
|
|
|
uint64_t sectors_size_on_disk; |
|
|
|
uint64_t next_free_sector; |
|
|
|
uint64_t number_of_mtt; |
|
|
|
uint64_t master_tag_records[16]; |
|
|
|
} __attribute__((packed)) FSCI; |
|
|
|
|
|
|
|
typedef struct struct_global_tag { |
|
|
|
/* SizeOf this = |
|
|
|
* tagname |
|
|
|
* address |
|
|
|
* control_bits |
|
|
|
*/ |
|
|
|
char tagname[256]; |
|
|
|
lsfs_tag_id tag_table_index; |
|
|
|
struct { |
|
|
|
uint64_t is_filename : 1; |
|
|
|
} control_bits; |
|
|
|
} __attribute__((packed)) global_tag; |
|
|
|
|
|
|
|
|
|
|
|
typedef struct meta_information_format { |
|
|
|
char filename[246]; // remeber that the 246 bytes has to be a /0 terminator.. |
|
|
|
uint32_t owner_id; |
|
|
|
lsfs_tag_id tags[32]; |
|
|
|
uint64_t file_size; |
|
|
|
uint32_t control_bits; |
|
|
|
/* not pressent - Permission key table 64 bytes sha-265 pr. key*/ |
|
|
|
uint64_t creation_date; |
|
|
|
uint64_t last_modification_data; |
|
|
|
uint64_t last_access_date; |
|
|
|
/* |
|
|
|
* 256 first pointers in direct mapping to data |
|
|
|
* 94 next pointers is a pointer |
|
|
|
* 94 next pointers to pointers to data |
|
|
|
*/ |
|
|
|
lsfs_sector_offset one_level_pointer_data[MAX_NUM_ONE_LEVEL_DATA]; |
|
|
|
lsfs_sector_offset two_level_pointer_data[94]; |
|
|
|
lsfs_sector_offset three_level_pointer_data[94]; |
|
|
|
|
|
|
|
} __attribute__((packed)) mif; |
|
|
|
|
|
|
|
|
|
|
|
typedef struct tag_record { |
|
|
|
/* SIZE 16 bytes */ |
|
|
|
lsfs_file_id mif_record; |
|
|
|
struct { |
|
|
|
uint64_t is_filename : 1; |
|
|
|
} control_bits; |
|
|
|
|
|
|
|
} __attribute__((packed)) tag_record; |
|
|
|
|
|
|
|
|
|
|
|
int lsfs_disk_read_data_from_file(lsfs_file_id file_id, int buffer_size, void* buffer_for_data) { |
|
|
|
// TODO some offset, to tell where in the file we want to write |
|
|
|
mif* mif_record = calloc(1, SECTOR_SIZE); |
|
|
|
read_data_from_disk(file_id, mif_record); |
|
|
|
int return_val = 0; |
|
|
|
for (int i = 0; i < MAX_NUM_ONE_LEVEL_DATA; ++i) { |
|
|
|
if(mif_record->one_level_pointer_data[i] == 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
return_val += read_data_from_disk(mif_record->one_level_pointer_data[i], buffer_for_data + (SECTOR_SIZE * i)); |
|
|
|
i++; |
|
|
|
} |
|
|
|
|
|
|
|
time_t current_time; |
|
|
|
time ( ¤t_time ); |
|
|
|
|
|
|
|
mif_record->last_access_date = (uint64_t) current_time; |
|
|
|
write_data_to_disk(file_id, mif_record); |
|
|
|
free(mif_record); |
|
|
|
return return_val; |
|
|
|
} |
|
|
|
|
|
|
|
static inline time_t lsfs_disk_update_timestamps(mif *file) { |
|
|
|
return file->last_modification_data = file->last_access_date = time(NULL); |
|
|
|
} |
|
|
|
|
|
|
|
#define lsfs_num_sectors_for_size(x) (((x)+SECTOR_SIZE-1)&~(SECTOR_SIZE-1)) |
|
|
|
|
|
|
|
int lsfs_disk_write_data_to_file(lsfs_file_id file_id, int data_length, char *data) { |
|
|
|
int amount_written = data_length; |
|
|
|
|
|
|
|
mif mif_record; |
|
|
|
read_data_from_disk(file_id, &mif_record); |
|
|
|
|
|
|
|
lsfs_sector_offset current_sector = mif_record.file_size / SECTOR_SIZE; |
|
|
|
unsigned int offset_in_sector = mif_record.file_size % SECTOR_SIZE; |
|
|
|
|
|
|
|
char *tmp_buffer = malloc(SECTOR_SIZE); |
|
|
|
assert(tmp_buffer); |
|
|
|
|
|
|
|
read_data_from_disk(mif_record.one_level_pointer_data[current_sector], tmp_buffer); |
|
|
|
|
|
|
|
memcpy(tmp_buffer + offset_in_sector, data, SECTOR_SIZE-offset_in_sector); |
|
|
|
data_length -= SECTOR_SIZE-offset_in_sector; |
|
|
|
|
|
|
|
if (data_length < 0) { |
|
|
|
data_length = 0; |
|
|
|
} |
|
|
|
|
|
|
|
for (;;) { |
|
|
|
assert(current_sector <= MAX_NUM_ONE_LEVEL_DATA); |
|
|
|
write_data_to_disk(mif_record.one_level_pointer_data[current_sector++], tmp_buffer); |
|
|
|
if (data_length <= 0) break; |
|
|
|
|
|
|
|
data += SECTOR_SIZE; |
|
|
|
if (data_length >= SECTOR_SIZE) { |
|
|
|
memcpy(tmp_buffer, data, SECTOR_SIZE); |
|
|
|
data_length -= SECTOR_SIZE; |
|
|
|
} |
|
|
|
else { |
|
|
|
memset(tmp_buffer, 0, SECTOR_SIZE); |
|
|
|
memcpy(tmp_buffer, data, data_length); |
|
|
|
data_length = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
amount_written -= data_length; |
|
|
|
|
|
|
|
free(tmp_buffer); |
|
|
|
|
|
|
|
lsfs_disk_update_timestamps(&mif_record); |
|
|
|
mif_record.file_size += amount_written; // update file size |
|
|
|
|
|
|
|
write_data_to_disk(file_id, &mif_record); |
|
|
|
return amount_written; |
|
|
|
} |
|
|
|
|
|
|
|
time_t lsfs_disk_truncate_file(lsfs_file_id file_id) { |
|
|
|
mif file_mif; |
|
|
|
read_data_from_disk(file_id, &file_mif); |
|
|
|
time_t result = lsfs_disk_update_timestamps(&file_mif); |
|
|
|
file_mif.file_size = 0; |
|
|
|
write_data_to_disk(file_id, &file_mif); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
int lsfs_disk_rename_tag(lsfs_tag_id tag_id, char* new_tagname) { |
|
|
|
for (int i = 0; i < MAX_MASTER_TAGS; ++i) |
|
|
|
{ |
|
|
|
if(p_control.mtt_tags[i].tag_table_index == tag_id) { |
|
|
|
memset(p_control.mtt_tags[i].tagname, 0, sizeof(p_control.mtt_tags[i].tagname)); |
|
|
|
sprintf(p_control.mtt_tags[i].tagname, "%s", new_tagname); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
// free the sectors including the tag table |
|
|
|
|
|
|
|
// Save the changes to disk |
|
|
|
fseek ( disk , (p_control.fsci->master_tag_records[0] * SECTOR_SIZE) , SEEK_SET ); |
|
|
|
fwrite(p_control.mtt_tags, 1, sizeof(global_tag) * DEFAULT_MASTER_TAG_TABLE_SIZE, disk); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
int lsfs_disk_rename_file(lsfs_file_id file_id, const char* new_filename) { |
|
|
|
mif* mif_record = calloc(1, SECTOR_SIZE); |
|
|
|
read_data_from_disk(file_id, mif_record); |
|
|
|
|
|
|
|
memset(mif_record->filename, 0, sizeof(mif_record->filename)); |
|
|
|
sprintf(mif_record->filename, "%s", new_filename); |
|
|
|
|
|
|
|
time_t current_time; |
|
|
|
time ( ¤t_time ); |
|
|
|
|
|
|
|
mif_record->last_modification_data = (uint64_t) current_time; |
|
|
|
mif_record->last_access_date = (uint64_t) current_time; |
|
|
|
|
|
|
|
write_data_to_disk(file_id, mif_record); |
|
|
|
free(mif_record); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
int lsfs_disk_delete_file(lsfs_file_id file_id) { |
|
|
|
mif* mif_record = calloc(1, SECTOR_SIZE); |
|
|
|
read_data_from_disk(file_id, mif_record); |
|
|
|
|
|
|
|
for (int i = 0; i < MAX_TAGS_FOR_A_FILE; ++i) |
|
|
|
{ |
|
|
|
if(mif_record->tags[i] == 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
lsfs_disk_untag_file(mif_record->tags[i], file_id); |
|
|
|
} |
|
|
|
// TODO Delete/free all data sectors. |
|
|
|
// Delete/free the mif record sector. |
|
|
|
|
|
|
|
free(mif_record); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
int lsfs_disk_delete_tag(lsfs_tag_id tag_id) { |
|
|
|
tag_record* tag_table = calloc(64, SECTOR_SIZE); |
|
|
|
read_data_from_disk(tag_id, tag_table); |
|
|
|
|
|
|
|
for (int i = 0; i < MAX_TAGS_IN_TAG_TABLE; ++i) |
|
|
|
{ |
|
|
|
if(tag_table[i].mif_record == 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
lsfs_disk_untag_file(tag_id, tag_table[i].mif_record); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int truncate_table = 0; |
|
|
|
|
|
|
|
for (int i = 0; i < MAX_MASTER_TAGS; ++i) |
|
|
|
{ |
|
|
|
if(p_control.mtt_tags[i].tag_table_index == tag_id) { |
|
|
|
p_control.mtt_tags[i] = p_control.mtt_tags[i+1]; |
|
|
|
truncate_table = 1; |
|
|
|
printf("Tag deleted from master table - TagID: %lu\n", tag_id); |
|
|
|
} |
|
|
|
else if (truncate_table) { |
|
|
|
p_control.mtt_tags[i] = p_control.mtt_tags[i+1]; |
|
|
|
if (p_control.mtt_tags[i+1].tag_table_index == 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// free the sectors including the tag table |
|
|
|
|
|
|
|
// Save the changes to disk |
|
|
|
fseek ( disk , (p_control.fsci->master_tag_records[0] * SECTOR_SIZE) , SEEK_SET ); |
|
|
|
fwrite(p_control.mtt_tags, 1, sizeof(global_tag) * DEFAULT_MASTER_TAG_TABLE_SIZE, disk); |
|
|
|
free(tag_table); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
int lsfs_disk_tag_file(lsfs_tag_id tag_id, lsfs_file_id file_id) { |
|
|
|
mif* mif_record = calloc(1, SECTOR_SIZE); |
|
|
|
read_data_from_disk(file_id, mif_record); |
|
|
|
|
|
|
|
for (int i = 0; i < MAX_TAGS_FOR_A_FILE; ++i) |
|
|
|
{ |
|
|
|
if(mif_record->tags[i] == 0) { |
|
|
|
mif_record->tags[i] = tag_id; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
write_data_to_disk(file_id, mif_record); |
|
|
|
free(mif_record); |
|
|
|
|
|
|
|
tag_record* tag_table = calloc(64, SECTOR_SIZE); |
|
|
|
read_data_from_disk(tag_id, tag_table); |
|
|
|
|
|
|
|
for (int i = 0; i < MAX_TAGS_IN_TAG_TABLE; ++i) |
|
|
|
{ |
|
|
|
if(tag_table[i].mif_record == 0) { |
|
|
|
tag_table[i].mif_record = file_id; |
|
|
|
printf("file tagged - TagID: %lu - FileID: %lu \n", tag_table[i].mif_record, file_id); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
write_data_to_disk(tag_id, tag_table); |
|
|
|
free(tag_table); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
int lsfs_disk_untag_file(lsfs_tag_id tag_id, lsfs_file_id file_id) { |
|
|
|
mif* mif_record = calloc(1, SECTOR_SIZE); |
|
|
|
read_data_from_disk(file_id, mif_record); |
|
|
|
int truncate_table = 0; |
|
|
|
|
|
|
|
for (int i = 0; i < MAX_TAGS_FOR_A_FILE; ++i) |
|
|
|
{ |
|
|
|
if(mif_record->tags[i] == tag_id) { |
|
|
|
mif_record->tags[i] = mif_record->tags[i+1]; |
|
|
|
truncate_table = 1; |
|
|
|
printf("file untagged - TagID: %lu - FileID: %lu \n", tag_id, file_id); |
|
|
|
} |
|
|
|
else if (truncate_table) { |
|
|
|
mif_record->tags[i] = mif_record->tags[i+1]; |
|
|
|
if (mif_record->tags[i+1] == 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
time_t current_time; |
|
|
|
time ( ¤t_time ); |
|
|
|
|
|
|
|
mif_record->last_modification_data = (uint64_t) current_time; |
|
|
|
mif_record->last_access_date = (uint64_t) current_time; |
|
|
|
|
|
|
|
write_data_to_disk(file_id, mif_record); |
|
|
|
free(mif_record); |
|
|
|
|
|
|
|
tag_record* tag_table = calloc(64, SECTOR_SIZE); |
|
|
|
read_data_from_disk(tag_id, tag_table); |
|
|
|
truncate_table = 0; |
|
|
|
|
|
|
|
for (int i = 0; i < MAX_TAGS_IN_TAG_TABLE; ++i) |
|
|
|
{ |
|
|
|
if(tag_table[i].mif_record == file_id) { |
|
|
|
tag_table[i].mif_record = tag_table[i+1].mif_record; |
|
|
|
truncate_table = 1; |
|
|
|
printf("file untagged - TagID: %lu - FileID: %lu \n", tag_table[i].mif_record, file_id); |
|
|
|
} |
|
|
|
else if (truncate_table) { |
|
|
|
tag_table[i].mif_record = tag_table[i+1].mif_record; |
|
|
|
if (tag_table[i+1].mif_record == 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
write_data_to_disk(tag_id, tag_table); |
|
|
|
free(tag_table); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
lsfs_tag_id lsfs_disk_create_tag(char* tag_name, bool is_filename) { |
|
|
|
/* Return ID of new tag, oterwise return 0 */ |
|
|
|
lsfs_tag_id* free_sectors; |
|
|
|
// Returns an array, with the sector numbers that is assignt to you |
|
|
|
free_sectors = calloc(DEFAULT_TAG_TABLE_SIZE, sizeof(lsfs_tag_id)); |
|
|
|
get_free_sectors(DEFAULT_TAG_TABLE_SIZE, free_sectors); // has to be freed |
|
|
|
|
|
|
|
// Insert tag in the master tag, table an set the pointer to the first of the tag table |
|
|
|
int index_in_mtt = 0; |
|
|
|
while(p_control.mtt_tags[index_in_mtt].tag_table_index != 0) { |
|
|
|
//TODO also have to count if we enter next data section. |
|
|
|
index_in_mtt++; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
p_control.mtt_tags[index_in_mtt].tag_table_index = free_sectors[0]; |
|
|
|
printf("%lu\n", free_sectors[0]); |
|
|
|
sprintf(p_control.mtt_tags[index_in_mtt].tagname, "%s", tag_name); |
|
|
|
p_control.mtt_tags[index_in_mtt].control_bits.is_filename = is_filename; |
|
|
|
|
|
|
|
tag_record new_tag[DEFAULT_TAG_TABLE_SIZE]; |
|
|
|
memset(new_tag, 0, (DEFAULT_TAG_TABLE_SIZE * sizeof(tag_record))); |
|
|
|
|
|
|
|
//printf("Sector number: %lu, is assignt to you \n", (*free_sectors)); |
|
|
|
//char* data = "red_file_1\nred_file_2\n"; |
|
|
|
//char* sector_to_write = write_mechanism_new_buffer(data); |
|
|
|
fseek ( disk , (p_control.fsci->master_tag_records[0] * SECTOR_SIZE) , SEEK_SET ); |
|
|
|
fwrite(p_control.mtt_tags, 1, sizeof(global_tag) * DEFAULT_MASTER_TAG_TABLE_SIZE, disk); |
|
|
|
|
|
|
|
fseek ( disk , ((*free_sectors) * SECTOR_SIZE) , SEEK_SET ); |
|
|
|
fwrite(new_tag, 1, DEFAULT_TAG_TABLE_SIZE * sizeof(tag_record), disk); |
|
|
|
|
|
|
|
//free(sector_to_write); |
|
|
|
int return_value = free_sectors[0]; |
|
|
|
free(free_sectors); |
|
|
|
return return_value; |
|
|
|
} |
|
|
|
|
|
|
|
int get_free_sectors(int num_sectors_needed, lsfs_sector_offset* output_array) { |
|
|
|
/* |
|
|
|
* TODO - WARNING |
|
|
|
* This has to be a much better algoritm, to pick free sctors. |
|
|
|
* We have to keep some bookeeping of what is free. |
|
|
|
* Also if more sctors are claimed, we want them to be sequtive. |
|
|
|
* This is just a naiv counter, just added more sectors to the file. |
|
|
|
*/ |
|
|
|
|
|
|
|
if (num_sectors_needed > 1) { |
|
|
|
for (int i = 0; i < num_sectors_needed; ++i) |
|
|
|
{ |
|
|
|
output_array[i] = p_control.fsci->next_free_sector; |
|
|
|
p_control.fsci->next_free_sector++; |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
output_array[0] = p_control.fsci->next_free_sector; |
|
|
|
p_control.fsci->next_free_sector++; |
|
|
|
} |
|
|
|
printf("Sector %lu is assignt\n", output_array[0]); |
|
|
|
write_data_to_disk(0, p_control.fsci); |
|
|
|
return p_control.fsci->next_free_sector; |
|
|
|
} |
|
|
|
|
|
|
|
int create_file_system() { |
|
|
|
//char* sector_to_write; |
|
|
|
// make default File System Control information (FSCI) |
|
|
|
// first integer says how many pointers we got |
|
|
|
// to master tag tables |
|
|
|
// Second and forward is the pointers to the master Tag Tables |
|
|
|
// we need the first number to allocate memory at one go. |
|
|
|
int* zero_buffer; |
|
|
|
FSCI fsci; |
|
|
|
fsci.offset_on_disk = 1; |
|
|
|
fsci.maximum_sectors_on_partition = 1048576; // Max 4GiB |
|
|
|
fsci.next_free_sector = 257; |
|
|
|
fsci.number_of_mtt = 1; |
|
|
|
memset(fsci.master_tag_records, 0, 128); |
|
|
|
fsci.master_tag_records[0] = 1; |
|
|
|
|
|
|
|
fseek ( disk , 0, SEEK_SET ); |
|
|
|
fwrite(&fsci, 1, sizeof(fsci), disk); |
|
|
|
zero_buffer = calloc(1, (4096 - sizeof(fsci))); |
|
|
|
fwrite(zero_buffer, 1, (4096 - sizeof(fsci)), disk); |
|
|
|
free(zero_buffer); |
|
|
|
/* MASTER TAG TABLE */ |
|
|
|
|
|
|
|
global_tag mtt_tags[DEFAULT_MASTER_TAG_TABLE_SIZE]; |
|
|
|
memset(mtt_tags, 0, (DEFAULT_MASTER_TAG_TABLE_SIZE * sizeof(global_tag))); |
|
|
|
|
|
|
|
fwrite(&mtt_tags, 1, sizeof(mtt_tags), disk); |
|
|
|
zero_buffer = calloc(1, 16); |
|
|
|
fwrite(zero_buffer, 1, 16, disk); |
|
|
|
free(zero_buffer); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int lsfs_disk_load_disk() { |
|
|
|
|
|
|
|
// First we find the Mater Table. |
|
|
|
fseek ( disk , 1 * SECTOR_SIZE, SEEK_SET ); |
|
|
|
fread(p_control.mtt_tags, 1, sizeof(global_tag) * DEFAULT_MASTER_TAG_TABLE_SIZE , disk); |
|
|
|
|
|
|
|
// Now we can finde the FSCI data |
|
|
|
fseek ( disk , 0, SEEK_SET ); |
|
|
|
fread(p_control.fsci, 1, sizeof(FSCI), disk); |
|
|
|
|
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
lsfs_tag_id lsfs_disk_create_file(char* filename, lsfs_tag_id* tags, void* file_data) { |
|
|
|
|
|
|
|
// create space for mif |
|
|
|
mif new_file_data; |
|
|
|
lsfs_tag_id return_id; |
|
|
|
|
|
|
|
|
|
|
|
memset(new_file_data.filename, 0, sizeof(new_file_data.filename)); |
|
|
|
sprintf(new_file_data.filename, "%s", filename); // remeber that the 260 bytes has to be a /0 terminator. // 260 because it pads to a full sector. |
|
|
|
|
|
|
|
printf("%s\n", new_file_data.filename); |
|
|
|
new_file_data.owner_id = getuid(); |
|
|
|
|
|
|
|
lsfs_tag_id* index_to_mif_data; |
|
|
|
index_to_mif_data = calloc(1, sizeof(lsfs_tag_id)); |
|
|
|
get_free_sectors(1, index_to_mif_data); // has to be freed |
|
|
|
|
|
|
|
memset(new_file_data.tags, 0, (32 * sizeof(lsfs_tag_id))); |
|
|
|
|
|
|
|
new_file_data.file_size = 0; |
|
|
|
|
|
|
|
time_t current_time; |
|
|
|
time ( ¤t_time ); |
|
|
|
|
|
|
|
new_file_data.creation_date = (uint64_t) current_time; |
|
|
|
new_file_data.last_modification_data = (uint64_t) current_time; |
|
|
|
new_file_data.last_access_date = (uint64_t) current_time; |
|
|
|
|
|
|
|
new_file_data.control_bits = 0; |
|
|
|
memset(new_file_data.one_level_pointer_data, 0, (256 * sizeof(lsfs_sector_offset))); |
|
|
|
memset(new_file_data.two_level_pointer_data, 0, (94 * sizeof(lsfs_sector_offset))); |
|
|
|
memset(new_file_data.three_level_pointer_data, 0, (94 * sizeof(lsfs_sector_offset))); |
|
|
|
get_free_sectors(1, new_file_data.one_level_pointer_data); |
|
|
|
int actual_file_size = 0; |
|
|
|
|
|
|
|
new_file_data.file_size = actual_file_size; |
|
|
|
fseek ( disk , index_to_mif_data[0] * SECTOR_SIZE, SEEK_SET ); |
|
|
|
fwrite(&new_file_data, 1, SECTOR_SIZE, disk); |
|
|
|
|
|
|
|
printf("MIF written at sector: %lu\n", index_to_mif_data[0]); |
|
|
|
printf("DATA written at sector: %lu\n", new_file_data.one_level_pointer_data[0]); |
|
|
|
|
|
|
|
int i = 0; |
|
|
|
if (tags != NULL) { |
|
|
|
while(tags[i] != 0) { |
|
|
|
printf("A tag is found \n"); |
|
|
|
lsfs_disk_tag_file(tags[i], index_to_mif_data[0]); |
|
|
|
new_file_data.tags[i] = tags[i]; |
|
|
|
i++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return_id = index_to_mif_data[0]; |
|
|
|
free(index_to_mif_data); |
|
|
|
return return_id; |
|
|
|
} |
|
|
|
|
|
|
|
int write_data_to_disk(lsfs_sector_offset index, void* data_to_write) { |
|
|
|
fseek ( disk, (index * SECTOR_SIZE), SEEK_SET ); // SEEK_SET start offset at index 0 and move 1 * SECTOR_SIZE, and write here. |
|
|
|
int written = fwrite(data_to_write, 1, SECTOR_SIZE, disk); |
|
|
|
return written; |
|
|
|
} |
|
|
|
|
|
|
|
int write_data_to_disk_off(lsfs_sector_offset index, void* data_to_write, int offset) { |
|
|
|
fseek ( disk, (index * SECTOR_SIZE) + offset, SEEK_SET ); // SEEK_SET start offset at index 0 and move 1 * SECTOR_SIZE, and write here. |
|
|
|
int written = fwrite(data_to_write, 1, SECTOR_SIZE, disk); |
|
|
|
return written; |
|
|
|
} |
|
|
|
|
|
|
|
int read_data_from_disk(lsfs_sector_offset index, void* data_buffer) { |
|
|
|
fseek ( disk, (index * SECTOR_SIZE ), SEEK_SET ); // SEEK_SET start offset at index 0 and move 1 * SECTOR_SIZE, and write here. |
|
|
|
int read = fread(data_buffer, 1, SECTOR_SIZE, disk); |
|
|
|
return read; |
|
|
|
} |
|
|
|
|
|
|
|
#endif |