Seperation lsfs source
This commit is contained in:
1 parent
4569c9e174
commit
a2953d1dbb
11 files changed
+8
-1308
No files matched your search
@@ -0,0 +1,2 @@
|
|||||||
|
*.img
|
||||||
|
*.o
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "source_lsfs"]
|
||||||
|
path = source_lsfs
|
||||||
|
url = git@git.imada.sdu.dk:Sandsized/LSFS.git
|
||||||
BIN
Binary file not shown.
@@ -1,278 +0,0 @@
|
|||||||
#include <sys/stat.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
@@ -1,876 +0,0 @@
|
|||||||
#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 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
|
|
||||||
+2
-2
@@ -5,7 +5,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "lsfs_disk_controller.h"
|
#include "source_lsfs/lsfs_disk_controller.h"
|
||||||
|
|
||||||
int lsfs_getattr( const char *, struct stat * );
|
int lsfs_getattr( const char *, struct stat * );
|
||||||
int lsfs_mkdir(const char *path, mode_t mode);
|
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[] ) {
|
int main( int argc, char *argv[] ) {
|
||||||
// "/home/rhodez-x/Documents/github/SingOS/SingOS.img"
|
// "/home/rhodez-x/Documents/github/SingOS/SingOS.img"
|
||||||
//disk = fopen ("/home/rhodezx/Documents/github/SingOS/SingOS.img", "r+b");
|
//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())
|
if (lsfs_disk_load_disk())
|
||||||
{
|
{
|
||||||
return fuse_main( argc, argv, &lsfs_oper );
|
return fuse_main( argc, argv, &lsfs_oper );
|
||||||
|
|||||||
BIN
Binary file not shown.
-152
@@ -1,152 +0,0 @@
|
|||||||
#ifndef LSFS_STRING_H
|
|
||||||
#define LSFS_STRING_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
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
|
|
||||||
Submodule
+1
Submodule source_lsfs added at 340cacc8f5.
Reference in new issue
Block a user