|
|
- #ifndef LSFS_DISK_CONTROLLER_H
- #define LSFS_DISK_CONTROLLER_H
-
- #include <errno.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>
-
- #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 uint64_t lsfs_sector_offset;
- typedef lsfs_sector_offset lsfs_file_id;
-
- typedef enum
- {
- // 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 uint64_t sector_index;
- static FILE* disk = NULL;
- 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, struct_table_entry* table_entry);
- int lsfs_disk_read_data_from_file(lsfs_file *file, int data_length, char *data, int64_t offset_to_next_entry);
- int lsfs_disk_write_data_to_file(lsfs_file* file, int data_length, char *data, int64_t offset_to_next_entry);
- int lsfs_disk_rename_file(const char* old_filename_, const char* new_filename);
- int lsfs_disk_load_disk(char* diskname);
- 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 32 // 2048 // Sectors
- #define SPACE_VBR_RECORD 32 // 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 8 // 16
- #define NUM_DATA_POINTERS 27
-
- 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;
- struct_table_entry* table_backpointer;
- 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->table_backpointer = &(dir_table->entries[i]);
- 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, int64_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, int64_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->table_backpointer))
- {
- // 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, struct_table_entry* table_entry) {
-
- 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 (table_entry->data_pointer[i] == 0)
- {
- // If free we can assign:
- table_entry->data_pointer[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 == '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 = SPACE_MBR_RECORD;
- 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 == '1') || (hdd_or_partition == '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-a4\r\n(LessSimpelFileSystem)(Generated by the disk_manager_utility.c)\r\nDeveloped to SingOS and QuasiOS\r\nby Jorn Guldberg\r\n");
-
- if (hdd_or_partition == '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);
-
- lsfs_disk_load_disk(NULL); // Reload disk
- 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.
-
- lsfs_disk_load_disk(NULL); // Reload 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: %lu\n", vbr_first_sector->vbr_size_in_bytes);
- printf("VBR lba address: %lu\n", vbr_first_sector->vbr_LBA_address);
- printf("VBR FSCI: %lu\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(char* diskname)
- {
- // Find the partition talbe:
- // This makes is BIOS dependent.
- // UEFI is not supported.
- if (diskname != NULL)
- {
- disk = fopen ( diskname , "r+b" );
-
- }
- else if (disk == NULL )
- {
- return -1;
- }
-
- 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]));
- }
- 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
|