diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..305ee56 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.img +*.o diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..10aa678 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "source_lsfs"] + path = source_lsfs + url = git@git.imada.sdu.dk:Sandsized/LSFS.git diff --git a/SingOS.img b/SingOS.img deleted file mode 100644 index 675577d..0000000 Binary files a/SingOS.img and /dev/null differ diff --git a/a.out b/a.out index 99a851b..a9d7cf2 100755 Binary files a/a.out and b/a.out differ diff --git a/disk_manager_utility.c b/disk_manager_utility.c deleted file mode 100644 index f35aee8..0000000 --- a/disk_manager_utility.c +++ /dev/null @@ -1,278 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "lsfs_disk_controller.h" - - -static int disk_is_loaded = 0; -static char loaded_disk_name[256]; -static char input_buffer[256]; - -int dmu_print_file(char *path) { - printf("\n|-----------------Meta Information For File-----------------|\n"); - - lsfs_file *file = calloc(1, sizeof(lsfs_file)); - lsfs_disk_getattr(file, path); - - - printf("File ID: %lu\n", file->file_id); - printf("Filename: %s\n", file->filename); - printf("File size: %lu\n", file->size); - printf("Entry kind: %d", file->entry_kind); - printf("Index in directory table: %d", file->table_entry_pointer); - printf("Sector index on disk: %lu\n", file->table_entry_sector_index); - printf("\nData pointers:\n"); - for (int i = 0; i < NUM_DATA_POINTERS; ++i) - { - printf("%lu\n", file->data_pointer[i]); - } - /* - printf("\n|-------------------------File Data-------------------------|\n"); - char* file_data = calloc(MAX_NUM_ONE_LEVEL_DATA, SECTOR_SIZE); - int size_of_data = 0; - - size_of_data = lsfs_disk_read_data_from_file(fileID, (256*4096), file_data); - - if (size_of_data <= 0) { - printf("|File has no data!\n"); - } - for (int i = 0; i < MAX_NUM_ONE_LEVEL_DATA; ++i) - { - if (size_of_data <= 0) { - break; - } - printf("|%s", file_data); - size_of_data -= SECTOR_SIZE; - } - printf("\n|---------------------End File Data-------------------------|\n"); - */ - return 1; -} - -#if 0 -typedef struct sector_data -{ - char data[SECTOR_SIZE]; -} sector_data; - - -int dmu_install_SingOS(char* disk_name) { - disk = fopen ( disk_name , "r+b" ); - p_control.fsci = malloc(sizeof(FSCI)); - p_control.mtt_tags = malloc(sizeof(global_tag) * DEFAULT_MASTER_TAG_TABLE_SIZE); - lsfs_disk_load_disk(disk, &p_control); - - lsfs_tag_id untagged = lsfs_disk_create_tag("@untagged", false); - lsfs_tag_id sy_files = lsfs_disk_create_tag("@system_files", false); - lsfs_tag_id SingOS_files = lsfs_disk_create_tag("@SingOS", false); - - /* Add files: */ - char* new_file_data_d = calloc(1, 4096); - char* rtfm_file = "If you don't know the answer\nRead the F manual\n"; - sprintf(new_file_data_d, "%s", rtfm_file); - char* l_filename = "RTFM.md"; - lsfs_sector_offset* tags = calloc(2, sizeof(lsfs_sector_offset)); - lsfs_tag_id filename_tag = lsfs_disk_create_tag(l_filename, true); - tags[0] = filename_tag; - tags[1] = sy_files; - int rtfm_file_if = lsfs_disk_create_file(l_filename, tags, new_file_data_d ); - lsfs_disk_write_data_to_file(rtfm_file_if, strlen(rtfm_file), new_file_data_d); - - char* vip_file = "Very important file\n" ; - sprintf(new_file_data_d, "%s", vip_file); - l_filename = "system_control.md"; - filename_tag = lsfs_disk_create_tag(l_filename, true); - tags[0] = filename_tag; - tags[1] = sy_files; - int vip_file_id = lsfs_disk_create_file(l_filename, tags, new_file_data_d ); - lsfs_disk_write_data_to_file(vip_file_id, strlen(vip_file), new_file_data_d); - - char* sing_os_file = "SingOS is comming\n\nWe are not ready to expose the binaries nor the source\nBut read more @ guld-berg.dk/singos\nSingOS is real\n\n- groot\n" ; - sprintf(new_file_data_d, "%s", sing_os_file); - l_filename = "README.md"; - filename_tag = lsfs_disk_create_tag(l_filename, true); - tags[0] = filename_tag; - tags[1] = SingOS_files; - int sing_id = lsfs_disk_create_file(l_filename, tags, new_file_data_d ); - lsfs_disk_write_data_to_file(sing_id, strlen(sing_os_file), new_file_data_d); - - - free(new_file_data_d); - free(tags); - - fclose (disk); -} -#endif - -int dmu_create_file_system(char* disk_name) { - uint64_t filesystem_size_in_MB = 0; - char hdd_or_partition[8]; // 1: is harddisk, 2: is partition - char input_size_file_system[64]; // in MB - - do { - printf("Create as 1: harddrive or 2: as a single partition (enter 1 or 2): \n"); - scanf("%s", hdd_or_partition); - - } while ((hdd_or_partition[0] != '1') && (hdd_or_partition[0] != '2')); - - printf("Enter size of file system in MB (as an integer number): \n"); - scanf("%s", input_size_file_system); - - filesystem_size_in_MB = atoi(input_size_file_system); - - printf("Create new disk img\n"); - create_file_system(disk_name, hdd_or_partition, filesystem_size_in_MB); - printf("Disk is created as: %s\n", disk_name); - fclose (disk); - - // TODO: Do you want to install SingOS: - //dmu_install_SingOS(disk_name); - - return 1; -} - -int dmu_load_file_system(char* disk_name) { - disk = fopen ( disk_name , "r+b" ); - lsfs_disk_load_disk(); - disk_is_loaded = 1; - return 1; -} - -int dmu_install_bootloader(char* disk_name) { - lsfs_disk_install_bootloader(disk_name); - return 1; -} - -int dmu_install_vbr(char* disk_name) { - lsfs_disk_install_vbr(disk_name); - return 1; -} - -int dmu_print_mtt(char *path) { - Directory_Table *directory_table; - directory_table = lsfs_find_directory(path, false); - - printf("\n|------------------------ Directory ------------------------|Control_bits|\n"); - - for (int i = 0; i < DEFAULT_TABLE_SIZE; ++i) { - printf("|%-28s|%-30lu|%-12d| \n", directory_table->entries[i].filename, directory_table->entries[i].file_id, directory_table->entries[i].file_id); - printf("|-----------------------------------------------------------|------------|\n"); - - } - printf("\n\n\n"); - return 1; -} -#if 0 - - -int dmu_print_tag_table(lsfs_tag_id TagID) { - tag_record* tag_table = calloc(1, SECTOR_SIZE); - mif* mif_data = calloc(1, SECTOR_SIZE); - read_data_from_disk(TagID, tag_table); - - printf("Tag Table for: %lu\n", TagID); - printf("\n|------------------------Tag Table--------------------------|\n"); - - for (int i = 0; i < MAX_TAGS_IN_TAG_TABLE; ++i) { - if (tag_table[i].mif_record == 0) { - break; - } - read_data_from_disk(tag_table[i].mif_record, mif_data); - printf("|%-28lu|%-30s| \n", tag_table[i].mif_record, mif_data->filename); - printf("|-----------------------------------------------------------|\n"); - - } - printf("\n\n\n"); - return 1; -} -#endif - -int main (int argc, char *argv[]) -{ - - - char chose[8]; - while(strcmp(chose, "exit")) { - if(!disk_is_loaded) { - printf("Tag File System Utility\nMenu:\nc: Create new lsfs disk\nl: load disk\nEnter:"); - } - else { - printf("Tag File System Utility\nDisk loaded: %s\nMenu:\n1: Print Master Tag Table\n2: Print Tag Table\n3: Print File\n4: Create Tag\n5: Create New File\ni: install Bootloader\n", loaded_disk_name); - } - - scanf("%s", chose); - - if (strcmp(chose, "c") == 0) { - printf("\nCreate disk\nEnter filename:\n"); - scanf("%s", loaded_disk_name); - dmu_create_file_system(loaded_disk_name); - } - else if(strcmp(chose, "l") == 0) { - printf("\nLoad disk\nEnter filename:\n"); - scanf("%s", loaded_disk_name); - dmu_load_file_system(loaded_disk_name); - } - else if(strcmp(chose, "i") == 0) { - printf("\nInstall Bootloader\nEnter filename:\n"); - scanf("%s", input_buffer); - dmu_install_bootloader(input_buffer); - } - else if(strcmp(chose, "v") == 0) { - printf("\nInstall VBR\nEnter filename:\n"); - scanf("%s", input_buffer); - dmu_install_vbr(input_buffer); - } - else if(strcmp(chose, "1") == 0) { - // Print Directory: - printf("Enter Directory:\n"); - scanf("%s", input_buffer); - dmu_print_mtt(input_buffer); - } - else if(strcmp(chose, "3") == 0) { - // Print File - printf("Enter path:\n"); - scanf("%s", input_buffer); - - dmu_print_file( input_buffer ); - } - else if(strcmp(chose, "5") == 0) { - printf("Enter Directory:\n"); - scanf("%s", input_buffer); - - int new_id = lsfs_disk_create_entry(input_buffer, ENTRY_DIRECTORY ); - //lsfs_disk_write_data_to_file(new_id, strlen(new_file_data_d), new_file_data_d); - - } - - #if 0 - else if(strcmp(chose, "2") == 0) { - // Print Master Tag Table - printf("Enter Tag ID:\n"); - scanf("%s", input_buffer); - - dmu_print_tag_table( (lsfs_tag_id) atoi(input_buffer) ); - } - else if(strcmp(chose, "4") == 0) { - // Print Master Tag Table - printf("Enter Tag name:\n"); - scanf("%s", input_buffer); - lsfs_disk_create_tag(input_buffer, false); - } - - - printf("Write data:\n"); - char* new_file_data_d = calloc(1, 4096); - scanf("%s", new_file_data_d); - - - #endif - } - if(disk_is_loaded) { - fclose (disk); - } - - return 0; -} diff --git a/lsfs_disk_controller.h b/lsfs_disk_controller.h deleted file mode 100644 index 6800253..0000000 --- a/lsfs_disk_controller.h +++ /dev/null @@ -1,876 +0,0 @@ -#ifndef LSFS_DISK_CONTROLLER_H -#define LSFS_DISK_CONTROLLER_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "lsfs_string.h" - -typedef struct Directory_Table Directory_Table; -typedef struct struct_table_entry struct_table_entry; -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 struct lsfs_file lsfs_file; -typedef enum Table_Entry_Kind Table_Entry_Kind; - -typedef uint64_t lsfs_sector_offset; -typedef lsfs_sector_offset lsfs_file_id; - -//typedef uint64_t sector_index; -static FILE* disk; -static partition_control p_control; -static time_t timestamp_loading; - -int create_file_system(char* disk_name, char* hdd_or_partition, uint64_t filesystem_size_in_MB); -int lsfs_disk_create_entry(const char* path, Table_Entry_Kind entry_kind); -Directory_Table* lsfs_find_directory(const char* path, bool drop_filename); -int lsfs_disk_getattr(lsfs_file* find_file, const char *path); -int lsfs_disk_delete_entry(lsfs_file *file); -int get_free_sectors_table(); -int get_free_sectors(int num_sectors_needed, lsfs_sector_offset* output_array); -int lsfs_disk_read_data_from_file(lsfs_file *file, int data_length, char *data, size_t offset_to_next_entry); -int lsfs_disk_write_data_to_file(lsfs_file* file, int data_length, char *data, size_t offset_to_next_entry); -int lsfs_disk_rename_file(const char* old_filename_, const char* new_filename); -int lsfs_disk_load_disk(); -int write_data_to_disk(lsfs_sector_offset at_sector, uint32_t number_sectors, void* data_to_write); -int write_data_to_disk_off(lsfs_sector_offset index, uint32_t number_sectors, void* data_to_write, int offset); -int read_data_from_disk(lsfs_sector_offset index, uint32_t number_sectors, void* data_buffer); -int read_data_from_disk_off(lsfs_sector_offset index, uint32_t number_sectors, void* data_to_write, int offset); -int save_modified_file_information(lsfs_file* file); - -#define SPACE_MBR_RECORD 2048 // Sectors -#define SPACE_VBR_RECORD 2048 // Sectors -#define SIZE_FSCI_RECORD 1 // Sectors -#define DEFAULT_ENTRY_SIZE 1 // Sectors -#define SECTOR_SIZE 512 // BYTES -#define NUMBER_OF_MBR_PARTITIONS 4 -#define DEFAULT_DATA_POINTER_SIZE 8 // This is in sectors -#define DEFAULT_TABLE_SIZE 16 -#define NUM_DATA_POINTERS 27 - -typedef enum Table_Entry_Kind -{ - // These are specific values since, is has to corrospond to the implementation in assembly - ENTRY_EMPTY = 0, - ENTRY_FILE = 1, - ENTRY_DIRECTORY = 2, -} Table_Entry_Kind; - -typedef struct Partition_Entry -{ - uint8_t active_falg; // This has value 0x80 if it is a bootable partition / it is an active partition. - uint8_t CHS_start_addr[3]; // [0] = H, [1] = S, [2] = C - uint8_t partition_type; // This has a value such that one can idenfity which file system the partition is. - uint8_t CHS_last_addr[3]; // [0] = H, [1] = S, [2] = C - uint32_t LBA_abs_first_sector; - uint32_t number_of_sectors; - -} __attribute__((packed)) Partition_Entry; - -typedef struct Master_Boot_record -{ - uint8_t code[446]; // The code for the bootloader - Partition_Entry partitions[4]; - uint16_t mbr_signature; // Signature -} __attribute__((packed)) Master_Boot_record; - -typedef struct Volume_Boot_record -{ - uint8_t code[446]; // The code for the bootloader - uint64_t vbr_size_in_bytes; // Signature - uint64_t vbr_LBA_address; - uint64_t vbr_LBA_FSCI_position; - uint64_t not_used[5]; - uint16_t vbr_signature; // Signature -} __attribute__((packed)) Volume_Boot_record; - -typedef struct struct_table_entry -{ - char filename[256]; - lsfs_file_id file_id; - uint64_t file_size; - mif* ext_file_data; - uint32_t number_sectors; // This tells how many block there are allocated for the specific file. eg. we read this amount of bloks for the file. - uint8_t entry_kind; - uint8_t extra_control_bits1; - uint8_t extra_control_bits2; - uint8_t extra_control_bits3; - lsfs_sector_offset table_entry_sector_index; - lsfs_sector_offset data_pointer[NUM_DATA_POINTERS]; // if it is a directory, the first pointer will be to the next table. -} __attribute__((packed)) Table_Entry; - -typedef struct Directory_Table -{ - struct_table_entry entries[DEFAULT_TABLE_SIZE]; - -} __attribute__((packed)) Directory_Table; - -typedef struct File_System_Control_Information -{ - char filesystem_information[256]; - lsfs_sector_offset master_table_index; - lsfs_sector_offset this_partition_offset_on_disk; - lsfs_sector_offset next_free_sector; - uint64_t next_uniqe_id; // both files and directories gets this. - lsfs_sector_offset next_sector_reuse_pointer; - lsfs_sector_offset last_sector_index_on_partition; - lsfs_sector_offset maximum_sectors_on_disk; - lsfs_sector_offset sector_size_on_disk; - uint64_t not_used[24]; - -} __attribute__((packed)) FSCI; - -typedef struct struct_partition_control -{ - FSCI fsci; - Directory_Table master_table; -} __attribute__((packed)) partition_control; - - - -typedef struct meta_information_format { - char filename[246]; // remeber that the 246 bytes has to be a /0 terminator.. - uint32_t owner_id; - lsfs_file_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[NUM_DATA_POINTERS]; - 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; - -typedef struct lsfs_file { - lsfs_file_id file_id; - lsfs_sector_offset table_entry_pointer; - Table_Entry_Kind entry_kind; - char* filename; - uint32_t owner_id; - uint64_t size; - uint64_t creation_date; - uint64_t access_time; - uint64_t modification_time; - uint32_t number_sectors; - lsfs_sector_offset table_entry_sector_index; - lsfs_sector_offset data_pointer[NUM_DATA_POINTERS]; -} lsfs_file; - - -Directory_Table* lsfs_find_directory(const char *path, bool drop_filename) -{ - - Directory_Table *dir_table = calloc(1, sizeof(Directory_Table)); - printf("Table index: %lu \n",p_control.fsci.master_table_index ); - read_data_from_disk(p_control.fsci.master_table_index, DEFAULT_TABLE_SIZE, dir_table); - lsfs_string_array split_path = lsfs_string_split_c(path, '/', false); - - int number_of_traversal = split_path.length; - - if (drop_filename) - { - number_of_traversal -= 1; - } - - // Start from the master table - for (int i = 0; i < number_of_traversal; ++i) - { - for (int j = 0; j < DEFAULT_TABLE_SIZE; ++j) - { - if (strcmp(dir_table->entries[j].filename, split_path.strings[i].chars) == 0) - { - int index_sector = dir_table->entries[j].data_pointer[0]; - printf("Table index: %lu \n",index_sector ); - read_data_from_disk(index_sector, DEFAULT_TABLE_SIZE, dir_table); - break; - } - } - } - return dir_table; -} - -int lsfs_disk_getattr(lsfs_file* find_file, const char* path) { - lsfs_string_array split_path = lsfs_string_split_c(path, '/', false); - lsfs_string filename = split_path.strings[split_path.length-1]; - - // Start from the master table - Directory_Table *dir_table = lsfs_find_directory(path, true); - - for (int i = 0; i < DEFAULT_TABLE_SIZE; ++i) - { - if(strcmp( filename.chars, dir_table->entries[i].filename ) == 0) { - find_file->file_id = dir_table->entries[i].file_id; - find_file->entry_kind = dir_table->entries[i].entry_kind; - find_file->table_entry_pointer = i; - find_file->filename = dir_table->entries[i].filename; - find_file->table_entry_sector_index = dir_table->entries[i].table_entry_sector_index; - find_file->owner_id = getuid(); - find_file->size = dir_table->entries[i].file_size; // dir_table->entries[i].data_pointer[0]; //; - find_file->creation_date = (uint64_t) timestamp_loading; - find_file->access_time = (uint64_t) timestamp_loading; - find_file->modification_time = (uint64_t) timestamp_loading; - memcpy(find_file->data_pointer, dir_table->entries[i].data_pointer, NUM_DATA_POINTERS * 8); - find_file->number_sectors = 1; // TODO: should be loaded from disk. - return 1; - } - } - return 0; -} - - - -int lsfs_disk_read_data_from_file(lsfs_file *file, int buffer_size, char *data, size_t offset_to_next_entry) -{ - int data_length = file->size - offset_to_next_entry; - int amount_read = 0; - int amount_to_read = 0; - int remaining_offset = offset_to_next_entry; - //printf("READ: buffer_size: %d\n", buffer_size); - //printf("READ: Data length: %d\n", data_length); - //printf("READ: Offset length: %d\n", offset_to_next_entry); - - - int data_pointer_index = 0; // start at first data pointer. - - if (data_length > buffer_size) - { - data_length = buffer_size; - } - - while(data_length > 0) // We have more to write - { - //printf("READ: Remaing Data length: %d\n", data_length); - if (remaining_offset == 0) - { - char *tmp_buffer = calloc(DEFAULT_DATA_POINTER_SIZE, SECTOR_SIZE); - assert(tmp_buffer); - - if (data_length < (DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE)) - { - amount_to_read = data_length; - } - else - { - amount_to_read = (DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE); - } - //read_data_from_disk(lsfs_sector_offset index, uint32_t number_sectors, void* data_buffer) - if (file->data_pointer[data_pointer_index] == 0) - { - break; - } - read_data_from_disk(file->data_pointer[data_pointer_index], DEFAULT_DATA_POINTER_SIZE, tmp_buffer); - memcpy((data + amount_read), tmp_buffer, amount_to_read); - data_length -= amount_to_read; - amount_read += amount_to_read; - data_pointer_index++; - free(tmp_buffer); - } - else if (remaining_offset < (DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE)) - { - char *tmp_buffer = calloc(1, (DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE)); - assert(tmp_buffer); - - if (data_length < ((DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE) - remaining_offset) ) - { - amount_to_read = data_length; - } - else - { - amount_to_read = ((DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE) - remaining_offset); - } - - read_data_from_disk(file->data_pointer[data_pointer_index], DEFAULT_DATA_POINTER_SIZE, tmp_buffer); - - memcpy(data, (tmp_buffer + remaining_offset), amount_to_read); - data_length -= amount_to_read; - amount_read += amount_to_read; - remaining_offset -= amount_to_read; - - data_pointer_index++; - free(tmp_buffer); - } - else - { - // We have to skip a whole data pointer: - remaining_offset -= (DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE); - data_pointer_index++; - } - - } - - time_t current_time; - time ( ¤t_time ); - file->access_time = current_time; - - return amount_read; - -} - -static inline time_t lsfs_disk_update_timestamps(lsfs_file *file) { - return file->modification_time = file->access_time = 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 *file, int data_length, char *data, size_t offset_to_next_entry) -{ - int new_filesize = data_length + offset_to_next_entry; - int amount_written = 0; - int amount_to_write = 0; - //printf("Data length: %d\n", data_length); - //printf("Offset length: %d\n", offset_to_next_entry); - - int data_pointer_index = 0; // start at first data pointer. - while(data_length > 0) // We have more to write - { - while (file->data_pointer[data_pointer_index] == 0) - { - // we have to assign a free sector - if (get_free_sectors(1, file->data_pointer)) - { - // This is a fail case, we cannot assign a new sector: - return amount_written; - } - } - - if (offset_to_next_entry == 0) - { - char *tmp_buffer = calloc(DEFAULT_DATA_POINTER_SIZE, SECTOR_SIZE); - assert(tmp_buffer); - - if (data_length < (DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE)) - { - amount_to_write = data_length; - } - else - { - amount_to_write = (DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE); - } - - memcpy(tmp_buffer, (data + amount_written), amount_to_write); - data_length -= amount_to_write; - amount_written += amount_to_write; - - write_data_to_disk(file->data_pointer[data_pointer_index], DEFAULT_DATA_POINTER_SIZE, tmp_buffer); - data_pointer_index++; - free(tmp_buffer); - } - else if (offset_to_next_entry < (DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE)) - { - char *tmp_buffer = calloc(1, (DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE)); - assert(tmp_buffer); - read_data_from_disk(file->data_pointer[data_pointer_index], DEFAULT_DATA_POINTER_SIZE, tmp_buffer); - - if (data_length < ((DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE) - offset_to_next_entry) ) - { - amount_to_write = data_length; - } - else - { - amount_to_write = ((DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE) - offset_to_next_entry); - } - - - memcpy(tmp_buffer + offset_to_next_entry, data, amount_to_write); - data_length -= amount_to_write; - amount_written += amount_to_write; - offset_to_next_entry -= amount_to_write; - - write_data_to_disk(file->data_pointer[data_pointer_index], DEFAULT_DATA_POINTER_SIZE, tmp_buffer); - data_pointer_index++; - free(tmp_buffer); - } - else - { - // We have to skip a whole data pointer: - offset_to_next_entry -= (DEFAULT_DATA_POINTER_SIZE * SECTOR_SIZE); - //printf("Skip, offset is now: %d\n", offset_to_next_entry); - data_pointer_index++; - } - - } - - - time_t current_time; - time ( ¤t_time ); - //lsfs_disk_update_timestamps(&mif_record); - file->size = new_filesize; // update file size - - file->access_time = current_time; - file->modification_time = current_time; - - save_modified_file_information(file); - //write_data_to_disk(file->file_id, 4, &p_control.master_table[file->file_id]); - - // Should return the total new file size - //printf("We Think that we have written: %d \n", amount_written); - return amount_written; -} - -time_t lsfs_disk_truncate_file(lsfs_file *file, off_t offset) { - //mif file_mif; - //read_data_from_disk(file_id, &file_mif); - - time_t result = lsfs_disk_update_timestamps(file); - file->size = (int) offset; // p_control.master_table.entries[i].data_pointer[0]; //; - - save_modified_file_information(file); - //write_data_to_disk(file->file_id, 4, NULL); - return result; -} - -int lsfs_disk_rename_file(const char* old_filename, const char* new_filename) { - - lsfs_file *old_file = calloc(1, sizeof(lsfs_file)); - lsfs_file *new_file = calloc(1, sizeof(lsfs_file)); - - lsfs_disk_getattr(old_file, old_filename); - if (old_file->entry_kind == ENTRY_FILE) - { - lsfs_disk_create_entry(new_filename, ENTRY_FILE); - } - else - { - lsfs_disk_create_entry(new_filename, ENTRY_DIRECTORY); - } - lsfs_disk_getattr(new_file, new_filename); - - new_file->file_id = old_file->file_id; - new_file->size = old_file->size; - // TODO(Jørn) The data pointer assignt to the new file should be released. - memcpy(new_file->data_pointer, old_file->data_pointer, NUM_DATA_POINTERS * 8); - save_modified_file_information(new_file); - lsfs_disk_delete_entry(old_file); - - return 0; -} - -int lsfs_disk_delete_entry(lsfs_file *file) { - //printf("file: %s - has been deleted \n", file->filename); - Table_Entry *zero_buffer = calloc(1, (DEFAULT_ENTRY_SIZE * SECTOR_SIZE)); - //read_data_from_disk(file_id, 1, mif_record); - write_data_to_disk(file->table_entry_sector_index, DEFAULT_ENTRY_SIZE, zero_buffer); - - free(zero_buffer); - return 1; -} - -int lsfs_disk_delete_directory(const char *path) { - // Find the directory and check if this is empty for entries: - Directory_Table *directory_table = calloc(1, (DEFAULT_ENTRY_SIZE * SECTOR_SIZE)); - directory_table = lsfs_find_directory(path, false); - bool empty = true; - - for (int i = 0; i < DEFAULT_TABLE_SIZE; ++i) - { - if (directory_table->entries[i].entry_kind != 0) - { - empty = false; - } - } - free(directory_table); - - if (!empty) - { - return 1; - } - - lsfs_file *file = calloc(1, sizeof(lsfs_file)); - lsfs_disk_getattr(file, path); - - Table_Entry *zero_buffer = calloc(1, (DEFAULT_ENTRY_SIZE * SECTOR_SIZE)); - //read_data_from_disk(file_id, 1, mif_record); - write_data_to_disk(file->table_entry_sector_index, DEFAULT_ENTRY_SIZE, zero_buffer); - - free(zero_buffer); - - return 0; -} - -int get_free_sectors_table() { - // We need DEFAULT_TABLE_SIZE sectors straight contigious for a table - // Otherwise the file system cannot make a new table. - // We return the offset where the table is starting. - // If we cannot assing DEFAULT_TABLE_SIZE sectors, we report errror. - - int return_index = p_control.fsci.next_free_sector; - - if ((p_control.fsci.next_free_sector + DEFAULT_TABLE_SIZE) > p_control.fsci.last_sector_index_on_partition) - { - // We don't have space, report error - return -EINVAL; - } - p_control.fsci.next_free_sector += DEFAULT_TABLE_SIZE; - - fseek ( disk , ((p_control.fsci.this_partition_offset_on_disk) * SECTOR_SIZE), SEEK_SET ); - fwrite(&p_control.fsci, 1, SECTOR_SIZE, disk); - //printf("Table has got assigned Sector: %d\n", return_index); - return return_index; -} - -int get_free_sectors(int num_sectors_needed, lsfs_sector_offset* output_array) { - - if ((p_control.fsci.next_free_sector + num_sectors_needed) > p_control.fsci.last_sector_index_on_partition ) - { - // We cannot assign what we want. - return -EINVAL; - } - - int i = 0; - while (num_sectors_needed > 0) - { - if (i > NUM_DATA_POINTERS) - { - return -EINVAL; // We don't have any more data pointers. - } - - if (output_array[i] == 0) - { - // If free we can assign: - output_array[i] = p_control.fsci.next_free_sector; - p_control.fsci.next_free_sector += DEFAULT_DATA_POINTER_SIZE; - num_sectors_needed--; - } - i++; - } - - fseek ( disk , (p_control.fsci.this_partition_offset_on_disk) * SECTOR_SIZE, SEEK_SET ); - fwrite(&p_control.fsci, 1, SECTOR_SIZE, disk); - - return 0; -} - -int create_file_system(char* disk_name, char* hdd_or_partition, uint64_t filesystem_size_in_MB) { - //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. - FSCI *fsci = calloc(1, sizeof(FSCI)); - // Create disk on host system: - - disk = fopen ( disk_name , "wb" ); - ftruncate(fileno(disk), (filesystem_size_in_MB * 2048 * 512)); - - if (hdd_or_partition[0] == '1') - { - // This is the create hdd case - // This means that we setup the partition table. - Master_Boot_record *mbr = calloc(1, sizeof(Master_Boot_record)); - mbr->partitions[0].partition_type = 0x18; - mbr->partitions[0].LBA_abs_first_sector = 2048; - mbr->partitions[0].number_of_sectors = filesystem_size_in_MB * 2048; - mbr->mbr_signature = 0xaa55; - write_data_to_disk(0, 1, mbr); // Write this to the first sector of the disk. - } - - - if ((hdd_or_partition[0] == '1') || (hdd_or_partition[0] == '2')) - { - // This is just a single partition - // And then the file system is the only thing in the system. - sprintf(fsci->filesystem_information, "LSFS v1.0.0-a1\r\n(LessSimpelFileSystem)(Generated by the disk_manager_utility.c)\r\nDeveloped to SingOS\r\nby Jorn Guldberg\r\n"); - - if (hdd_or_partition[0] == '1') - { - fsci->this_partition_offset_on_disk = SPACE_MBR_RECORD + SPACE_VBR_RECORD; - } - else - { - fsci->this_partition_offset_on_disk = SPACE_VBR_RECORD; - } - - fsci->master_table_index = fsci->this_partition_offset_on_disk + 1; - fsci->next_free_sector = fsci->master_table_index + DEFAULT_TABLE_SIZE; - fsci->next_uniqe_id = 1; - fsci->next_sector_reuse_pointer = 0; - fsci->last_sector_index_on_partition = filesystem_size_in_MB * 2048; // Todo, this is the ssectors pr MB, this should not be hardcoded. - fsci->maximum_sectors_on_disk = filesystem_size_in_MB * 2048; //TODO(Jørn) Not in use yet - fsci->sector_size_on_disk = SECTOR_SIZE; - } - else - { - // This is an error case, and we should not hit this case. - assert(NULL); - } - - write_data_to_disk(fsci->this_partition_offset_on_disk, 1, fsci); - - return 0; -} - -int lsfs_disk_install_bootloader(char *bootloader_name) -{ - FILE *bootloader = fopen ( bootloader_name , "r+b" ); - Master_Boot_record *bootloader_mbr = calloc(1, sizeof(Master_Boot_record)); - fseek(bootloader, 0 * SECTOR_SIZE, SEEK_SET); - fread(bootloader_mbr, 1, SECTOR_SIZE, bootloader); - - Master_Boot_record *mbr = calloc(1, sizeof(Master_Boot_record)); - fseek( disk , 0 * SECTOR_SIZE, SEEK_SET ); - fread(mbr, 1, SECTOR_SIZE, disk); - memcpy(mbr->code, bootloader_mbr->code, 446); - write_data_to_disk(0, 1, mbr); // Write this to the first sector of the disk. - return 0; -} - -int lsfs_disk_install_vbr(char *vbr_path) -{ - struct stat st; - stat(vbr_path, &st); - FILE *vbr = fopen ( vbr_path , "r+b" ); - Volume_Boot_record *vbr_first_sector = calloc(1, SECTOR_SIZE); - void *vbr_buffer_rest = calloc(1, (SPACE_VBR_RECORD * SECTOR_SIZE - 1)); - - // First load first sector - fseek(vbr, 0, SEEK_SET); - fread(vbr_first_sector, 1, SECTOR_SIZE, vbr); - - fseek(vbr, SECTOR_SIZE, SEEK_SET); - fread(vbr_buffer_rest, 1, (st.st_size - SECTOR_SIZE), vbr); - - vbr_first_sector->vbr_size_in_bytes = st.st_size; - vbr_first_sector->vbr_LBA_address = p_control.fsci.this_partition_offset_on_disk - SPACE_VBR_RECORD; - vbr_first_sector->vbr_LBA_FSCI_position = p_control.fsci.this_partition_offset_on_disk; - vbr_first_sector->vbr_signature = 0x1818; - - printf("VBR size: %d\n", vbr_first_sector->vbr_size_in_bytes); - printf("VBR lba address: %d\n", vbr_first_sector->vbr_LBA_address); - printf("VBR FSCI: %d\n", vbr_first_sector->vbr_LBA_FSCI_position); - - write_data_to_disk((p_control.fsci.this_partition_offset_on_disk - SPACE_VBR_RECORD), 1, vbr_first_sector); // Write this to the first sector of the disk. - write_data_to_disk((p_control.fsci.this_partition_offset_on_disk - SPACE_VBR_RECORD + 1), (SPACE_VBR_RECORD - 1), vbr_buffer_rest); // Write this to the first sector of the disk. - - Master_Boot_record mbr; - fseek( disk , 0 * SECTOR_SIZE, SEEK_SET ); - fread(&mbr, 1, sizeof(mbr), disk); - - - if (mbr.mbr_signature == 0xaa55 ) - { - mbr.partitions[0].active_falg = 0x80; // TODO(Jørn) Hardcoded partition. - write_data_to_disk(0, 1, &mbr); - } - else - { - return -EINVAL; - } - - return 0; -} - - -int lsfs_disk_load_disk() { - // Find the partition talbe: - // This makes is BIOS dependent. - // UEFI is not supported. - time(×tamp_loading); - - Master_Boot_record mbr; - fseek( disk , 0 * SECTOR_SIZE, SEEK_SET ); - fread(&mbr, 1, sizeof(mbr), disk); - if (mbr.mbr_signature != 0xaa55 ) - { - // Means that it is a sigle partition we try to mount - fseek(disk, (SPACE_VBR_RECORD * SECTOR_SIZE), SEEK_SET ); - fread(&p_control.fsci, 1, SECTOR_SIZE , disk); - //printf("next free sector: %d\n", p_control.fsci.next_free_sector); - //printf("next free ID: %d\n", p_control.fsci.next_uniqe_id); - - // next we find the Mater Table. - fseek (disk, (p_control.fsci.master_table_index * SECTOR_SIZE), SEEK_SET ); - fread(&p_control.master_table, 1, DEFAULT_TABLE_SIZE * SECTOR_SIZE , disk); - return 1; - } - else - { - for (int i = 0; i < NUMBER_OF_MBR_PARTITIONS; ++i) - { - // TODO (Jørn) We maybe wnat to optimize, such that we can detect if we have more than one partition opn the system. - if (mbr.partitions[i].partition_type == 0x18) - { - // First we find the File system control information. - fseek(disk , ((mbr.partitions[i].LBA_abs_first_sector + SPACE_VBR_RECORD) * SECTOR_SIZE), SEEK_SET ); - fread(&p_control.fsci, 1, SECTOR_SIZE , disk); - - // next we find the Mater Table. - fseek (disk, (p_control.fsci.master_table_index * SECTOR_SIZE), SEEK_SET ); - fread(&p_control.master_table, 1, DEFAULT_TABLE_SIZE * SECTOR_SIZE , disk); - - return 1; - } - } - } - return 0; -} - - -int lsfs_disk_create_entry(const char* path, Table_Entry_Kind entry_kind) -{ - - // First check if file exist: - lsfs_file *file = calloc(1, sizeof(lsfs_file)); - if (lsfs_disk_getattr(file, path)) - { - return -EINVAL; - } - free(file); - - // Start from the master table - int free_index = -1; // -1 is no index found. - Directory_Table *dir_table = calloc(1, sizeof(Directory_Table)); - read_data_from_disk(p_control.fsci.master_table_index, DEFAULT_TABLE_SIZE, dir_table); - lsfs_sector_offset table_disk_position = p_control.fsci.master_table_index; - - - lsfs_string_array split_path = lsfs_string_split_c(path, '/', false); - lsfs_string filename = split_path.strings[split_path.length-1]; - - //printf("spilt length: %d\n", split_path.length); - - for (int i = 0; i < split_path.length -1; ++i) - { - for (int j = 0; j < DEFAULT_TABLE_SIZE; ++j) - { - if (strcmp(dir_table->entries[j].filename, split_path.strings[i].chars) == 0) - { - // We have found the next directory to traverse. - //printf("Get next dir at sector: "); - table_disk_position = dir_table->entries[j].data_pointer[0]; - //printf("%d\n", table_disk_position); - read_data_from_disk(table_disk_position, DEFAULT_TABLE_SIZE, dir_table); - break; - } - } - } - - - for (int table_index = 0; table_index < DEFAULT_TABLE_SIZE; ++table_index) - { - // Find free index. - if (dir_table->entries[table_index].entry_kind == ENTRY_EMPTY) - { - // Set the free index, continue to see if the filename exist. - // if not -1, we have found a better index. - if (free_index == -1) - { - //printf("Index found for file: %d\n", table_index); - table_disk_position += table_index; // Abselout index in file system - free_index = table_index; - } - } - } - - if (free_index == -1) - { - // The table is full, and we cannot create an entry - return -EINVAL; - } - - // Find the entry for the file in the table structure: - dir_table->entries[free_index].file_id = p_control.fsci.next_uniqe_id; - p_control.fsci.next_uniqe_id++; - - sprintf(dir_table->entries[free_index].filename, "%s", filename.chars); - dir_table->entries[free_index].entry_kind = entry_kind; - dir_table->entries[free_index].table_entry_sector_index = table_disk_position; - if (entry_kind == ENTRY_DIRECTORY) - { - dir_table->entries[free_index].data_pointer[0] = get_free_sectors_table(); - dir_table->entries[free_index].file_size = DEFAULT_TABLE_SIZE * SECTOR_SIZE; - } - else if (entry_kind == ENTRY_FILE) - { - // We assign one data pointer consiting of DEFAULT_DATA_POINTER_SIZE sectors - dir_table->entries[free_index].file_size = 0; - get_free_sectors(1, dir_table->entries[free_index].data_pointer); - } - else - { - return -EINVAL; - } - - /* - find_file->creation_date = (uint64_t) current_time; - find_file->access_time = (uint64_t) current_time; - find_file->modification_time = (uint64_t) current_time; - find_file->data = p_control.master_table.entries[i].data_pointer; - find_file->owner_id = getuid(); - new_file_data.owner_id = getuid(); - time_t current_time; - time ( ¤t_time ); - */ - //printf("File is written to sector: %d\n", table_disk_position); - write_data_to_disk(table_disk_position, DEFAULT_ENTRY_SIZE, &dir_table->entries[free_index]); - return 0; -} - -int save_modified_file_information(lsfs_file* file) { - // Write the file struct into the table_entry, such that we can save the data correct. - - Table_Entry *entry = calloc(1, sizeof(Table_Entry)); - read_data_from_disk(file->table_entry_sector_index, DEFAULT_ENTRY_SIZE, entry); - - - //entry.file_id = file->file_id; - memcpy(entry->filename, file->filename, 256); - entry->file_size = file->size; // p_control.master_table.entries[i].data_pointer[0]; //; - memcpy(entry->data_pointer, file->data_pointer, NUM_DATA_POINTERS * 8); - - write_data_to_disk(file->table_entry_sector_index, DEFAULT_ENTRY_SIZE, entry); - return 0; -} - - -int write_data_to_disk(lsfs_sector_offset index, uint32_t number_sectors, 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, (number_sectors * SECTOR_SIZE), disk); - return written; -} - -int write_data_to_disk_off(lsfs_sector_offset index, uint32_t number_sectors, 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, ((number_sectors * SECTOR_SIZE) - offset), disk); - return written; -} - -int read_data_from_disk(lsfs_sector_offset index, uint32_t number_sectors, 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, (number_sectors * SECTOR_SIZE), disk); - return read; -} - -int read_data_from_disk_off(lsfs_sector_offset index, uint32_t number_sectors, 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 = fread(data_to_write, 1, ((number_sectors * SECTOR_SIZE) - offset), disk); - return written; -} -#endif diff --git a/lsfs_fuse b/lsfs_fuse deleted file mode 100755 index 61e5601..0000000 Binary files a/lsfs_fuse and /dev/null differ diff --git a/lsfs_fuse.c b/lsfs_fuse.c index 7e7ab8d..c651955 100644 --- a/lsfs_fuse.c +++ b/lsfs_fuse.c @@ -5,7 +5,7 @@ #include #include -#include "lsfs_disk_controller.h" +#include "source_lsfs/lsfs_disk_controller.h" int lsfs_getattr( const char *, struct stat * ); int lsfs_mkdir(const char *path, mode_t mode); @@ -208,7 +208,7 @@ int lsfs_mknod(const char *path, mode_t mode, dev_t device) { int main( int argc, char *argv[] ) { // "/home/rhodez-x/Documents/github/SingOS/SingOS.img" //disk = fopen ("/home/rhodezx/Documents/github/SingOS/SingOS.img", "r+b"); - disk = fopen ("SingOS.img", "r+b"); + disk = fopen ("newdisk.img", "r+b"); if (lsfs_disk_load_disk()) { return fuse_main( argc, argv, &lsfs_oper ); diff --git a/lsfs_fuse.o b/lsfs_fuse.o deleted file mode 100644 index 4bd6514..0000000 Binary files a/lsfs_fuse.o and /dev/null differ diff --git a/lsfs_string.h b/lsfs_string.h deleted file mode 100644 index d7eef4f..0000000 --- a/lsfs_string.h +++ /dev/null @@ -1,152 +0,0 @@ -#ifndef LSFS_STRING_H -#define LSFS_STRING_H - -#include - -typedef struct lsfs_string { - bool dynamic; - unsigned int length; - char *chars; -} lsfs_string; - -typedef struct lsfs_string_array { - unsigned int length; - lsfs_string *strings; -} lsfs_string_array; - - -static inline lsfs_string lsfs_make_id_string(uint64_t *id) { - return (lsfs_string){ - .dynamic = false, - .length = sizeof(*id), - .chars = (char *)id - }; -} - -static inline lsfs_string lsfs_create_id_string(uint64_t id) { - uint64_t *id_ = malloc(sizeof(id)); - *id_ = id; - return (lsfs_string){ - .dynamic = true, - .length = sizeof(id), - .chars = (char *)id_ - }; -} - -static inline lsfs_string lsfs_make_string(unsigned int length, const char *chars) { - return (lsfs_string){ - .dynamic = false, - .length = length, - .chars = (char *)chars - }; -} - -static inline lsfs_string lsfs_make_string_c(const char *cstring) { - return lsfs_make_string(strlen(cstring), cstring); -} - -static inline lsfs_string lsfs_create_string(unsigned int length, const char *chars) { - - char *copy = malloc(length + 1); // Space for null terminator - memcpy(copy, chars, length); - copy[length] = '\0'; - - return (lsfs_string){ - .dynamic = true, - .length = length, - .chars = copy - }; -} - -static inline lsfs_string lsfs_clone_string(lsfs_string string) { - return lsfs_create_string(string.length, string.chars); -} - -static inline void lsfs_destroy_string(lsfs_string string) { - if(string.dynamic) free(string.chars); -} - -static inline bool lsfs_string_equal(lsfs_string a, lsfs_string b) { - if (a.length != b.length) return false; - return strncmp(a.chars, b.chars, b.length) == 0; -} - -lsfs_string_array lsfs_create_string_array(size_t array_size) { - lsfs_string_array result; - result.length = array_size; - result.strings = malloc(array_size * sizeof(lsfs_string)); - return result; -} - -static inline void lsfs_destroy_string_array(lsfs_string_array array) { - for (unsigned int i = 0; i < array.length; ++i) { - lsfs_destroy_string(array.strings[i]); - } - free(array.strings); -} - - -lsfs_string_array lsfs_string_split(lsfs_string string, char delim, bool keep_delim) { - unsigned int i; - unsigned int last; - - unsigned int count = 0; - - i = 0; - last = 0; - while(i < string.length) { - if (string.chars[i] == delim) { - if (i > last+1) { - ++count; - } - last = i; - } - ++i; - } - if (i > last+1) { - ++count; - } - - lsfs_string_array result = lsfs_create_string_array(count); - - unsigned int insert_index = 0; - int k = keep_delim ? 0 : 1; - - i = 0; - last = 0; - while(i < string.length) { - if (string.chars[i] == delim) { - if (i > last+1) { - result.strings[insert_index++] = lsfs_create_string(i-(last+k), string.chars+(last+k)); - } - last = i; - } - ++i; - } - if (i > last+1) { - result.strings[insert_index++] = lsfs_create_string(i-(last+k), string.chars+(last+k)); - } - - return result; - -} - -static inline lsfs_string_array lsfs_string_split_c(const char *string, char delim, bool keep_delim) { - return lsfs_string_split(lsfs_make_string_c(string), delim, keep_delim); -} - -char *dbg_strarr(lsfs_string_array strings) { - static char temp[8192]; - memset(temp, 0, sizeof(temp)); - - int where = 0; - where += sprintf(temp+where, "{"); - for (unsigned int i = 0; i < strings.length; ++i) { - where += sprintf(temp+where, "<'%.*s'>", strings.strings[i].length, strings.strings[i].chars); - } - where += sprintf(temp+where, "}"); - - return temp; // @Leak -} - -#endif \ No newline at end of file diff --git a/source_lsfs b/source_lsfs new file mode 160000 index 0000000..340cacc --- /dev/null +++ b/source_lsfs @@ -0,0 +1 @@ +Subproject commit 340cacc8f5468531db857c6104eab1672defe082