diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3babbff --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +GCC = gcc +SOURCES = lsfs_fuse.c +OBJS := $(patsubst %.c,%.o,$(SOURCES)) +CFLAGS = -O0 -g -Wall -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=25 + +.always_rebuilt: + +## +# Libs +## +LIBS := fuse +LIBS := $(addprefix -l,$(LIBS)) + +all: tfs + +%.o: %.c .always_rebuilt + $(GCC) $(CFLAGS) -c -o $@ $< + +tfs: $(OBJS) .always_rebuilt + $(GCC) $(OBJS) $(LIBS) $(CFLAGS) -o lsfs_fuse + +clean: + rm -f $(OBJS) lsfs_fuse diff --git a/load.sh b/load.sh new file mode 100644 index 0000000..cca2784 --- /dev/null +++ b/load.sh @@ -0,0 +1 @@ +./lsfs_fuse lsfs_folder/ \ No newline at end of file diff --git a/lsfs_disk_controller.h b/lsfs_disk_controller.h new file mode 100644 index 0000000..7fba263 --- /dev/null +++ b/lsfs_disk_controller.h @@ -0,0 +1,565 @@ +#ifndef LSFS_DISK_CONTROLLER_H +#define LSFS_DISK_CONTROLLER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct struct_partition_control partition_control; +typedef struct struct_global_tag global_tag; +typedef struct struct_partition_control partition_control; +typedef struct File_System_Control_Information FSCI; +typedef struct meta_information_format mif; +typedef struct tag_record tag_record; + +typedef uint64_t lsfs_sector_offset; +typedef lsfs_sector_offset lsfs_file_id; +typedef lsfs_sector_offset lsfs_tag_id; + +//typedef uint64_t sector_index; +static FILE* disk; +static partition_control p_control; // used for debugging + +int create_file_system(); +lsfs_sector_offset lsfs_disk_create_tag(char* tag_name, bool is_filename); +lsfs_sector_offset lsfs_disk_create_file(char* filename, lsfs_tag_id* tags, void* file_data); +int lsfs_disk_untag_file(lsfs_tag_id tag_id, lsfs_file_id file_id); +int lsfs_disk_tag_file(lsfs_tag_id tag_id, lsfs_file_id file_id); +int lsfs_disk_delete_tag(lsfs_tag_id tag_id); +int lsfs_disk_delete_file(lsfs_file_id file_id); +int get_free_sectors(int num_sectors_needed, lsfs_sector_offset* output_array); +int lsfs_disk_read_data_from_file(lsfs_file_id file_id, int buffer_size, void* buffer_for_data); +int lsfs_disk_write_data_to_file(lsfs_file_id file_id, int data_length, char *data); +int lsfs_disk_rename_tag(lsfs_file_id file_id, char* new_tagname); +int lsfs_disk_rename_file(lsfs_file_id file_id, const char* new_filename); +int lsfs_disk_load_disk(); +int write_data_to_disk(lsfs_sector_offset at_sector, void* data_to_write); +int read_data_from_disk(lsfs_sector_offset index, void* data_buffer); +int write_data_to_disk_off(lsfs_sector_offset index, void* data_to_write, int offset); + + +#define SECTOR_SIZE 4096 +#define DEFAULT_FILE_SIZE 1 // This is in sectors +#define DEFAULT_MASTER_TAG_TABLE_SIZE 3855 // correspond to 1 MiB in sectors 3855 * 57825 +#define DEFAULT_TAG_TABLE_SIZE 64 // correspond to 262144 bytes in sectors - 16384 files pr. default. (minus one, the last is a pointer to a table more ) +#define MAX_MASTER_TAGS 57825 +#define MAX_TAGS_IN_TAG_TABLE 16384 +#define MAX_TAGS_FOR_A_FILE 32 + +#define MAX_NUM_ONE_LEVEL_DATA 256 // First Mib of a file. +#define MAX_NUM_TWO_LEVEL_DATA 94 // First Mib of a file. +#define MAX_NUM_THREE_LEVEL_DATA 94 // First Mib of a file. + +typedef struct struct_partition_control{ + FSCI* fsci; + global_tag* master_table; +} __attribute__((packed)) partition_control; + +typedef struct File_System_Control_Information { + uint64_t offset_on_disk; + uint64_t next_partition; + uint64_t maximum_sectors_on_partition; + uint64_t maximum_sectors_on_disk; + uint64_t sectors_size_on_disk; + uint64_t next_free_sector; + uint64_t number_of_mtt; + uint64_t master_tag_records[16]; +} __attribute__((packed)) FSCI; + +typedef struct struct_global_tag { + /* SizeOf this = + * tagname + * address + * control_bits + */ + char tagname[256]; + lsfs_tag_id tag_table_index; + struct { + uint64_t is_filename : 1; + } control_bits; +} __attribute__((packed)) global_tag; + + +typedef struct meta_information_format { + char filename[246]; // remeber that the 246 bytes has to be a /0 terminator.. + uint32_t owner_id; + lsfs_tag_id tags[32]; + uint64_t file_size; + uint32_t control_bits; + /* not pressent - Permission key table 64 bytes sha-265 pr. key*/ + uint64_t creation_date; + uint64_t last_modification_data; + uint64_t last_access_date; + /* + * 256 first pointers in direct mapping to data + * 94 next pointers is a pointer + * 94 next pointers to pointers to data + */ + lsfs_sector_offset one_level_pointer_data[MAX_NUM_ONE_LEVEL_DATA]; + lsfs_sector_offset two_level_pointer_data[94]; + lsfs_sector_offset three_level_pointer_data[94]; + +} __attribute__((packed)) mif; + + +typedef struct tag_record { + /* SIZE 16 bytes */ + lsfs_file_id mif_record; + struct { + uint64_t is_filename : 1; + } control_bits; + +} __attribute__((packed)) tag_record; + + +int lsfs_disk_read_data_from_file(lsfs_file_id file_id, int buffer_size, void* buffer_for_data) { + // TODO some offset, to tell where in the file we want to write + mif* mif_record = calloc(1, SECTOR_SIZE); + read_data_from_disk(file_id, mif_record); + int return_val = 0; + for (int i = 0; i < MAX_NUM_ONE_LEVEL_DATA; ++i) { + if(mif_record->one_level_pointer_data[i] == 0) { + break; + } + return_val += read_data_from_disk(mif_record->one_level_pointer_data[i], buffer_for_data + (SECTOR_SIZE * i)); + i++; + } + + time_t current_time; + time ( ¤t_time ); + + mif_record->last_access_date = (uint64_t) current_time; + write_data_to_disk(file_id, mif_record); + free(mif_record); + return return_val; +} + +static inline time_t lsfs_disk_update_timestamps(mif *file) { + return file->last_modification_data = file->last_access_date = time(NULL); +} + +#define lsfs_num_sectors_for_size(x) (((x)+SECTOR_SIZE-1)&~(SECTOR_SIZE-1)) + +int lsfs_disk_write_data_to_file(lsfs_file_id file_id, int data_length, char *data) { + int amount_written = data_length; + + mif mif_record; + read_data_from_disk(file_id, &mif_record); + + lsfs_sector_offset current_sector = mif_record.file_size / SECTOR_SIZE; + unsigned int offset_in_sector = mif_record.file_size % SECTOR_SIZE; + + char *tmp_buffer = malloc(SECTOR_SIZE); + assert(tmp_buffer); + + read_data_from_disk(mif_record.one_level_pointer_data[current_sector], tmp_buffer); + + memcpy(tmp_buffer + offset_in_sector, data, SECTOR_SIZE-offset_in_sector); + data_length -= SECTOR_SIZE-offset_in_sector; + + if (data_length < 0) { + data_length = 0; + } + + for (;;) { + assert(current_sector <= MAX_NUM_ONE_LEVEL_DATA); + write_data_to_disk(mif_record.one_level_pointer_data[current_sector++], tmp_buffer); + if (data_length <= 0) break; + + data += SECTOR_SIZE; + if (data_length >= SECTOR_SIZE) { + memcpy(tmp_buffer, data, SECTOR_SIZE); + data_length -= SECTOR_SIZE; + } + else { + memset(tmp_buffer, 0, SECTOR_SIZE); + memcpy(tmp_buffer, data, data_length); + data_length = 0; + } + } + + amount_written -= data_length; + + free(tmp_buffer); + + lsfs_disk_update_timestamps(&mif_record); + mif_record.file_size += amount_written; // update file size + + write_data_to_disk(file_id, &mif_record); + return amount_written; +} + +time_t lsfs_disk_truncate_file(lsfs_file_id file_id) { + mif file_mif; + read_data_from_disk(file_id, &file_mif); + time_t result = lsfs_disk_update_timestamps(&file_mif); + file_mif.file_size = 0; + write_data_to_disk(file_id, &file_mif); + return result; +} + +int lsfs_disk_rename_tag(lsfs_tag_id tag_id, char* new_tagname) { + for (int i = 0; i < MAX_MASTER_TAGS; ++i) + { + if(p_control.mtt_tags[i].tag_table_index == tag_id) { + memset(p_control.mtt_tags[i].tagname, 0, sizeof(p_control.mtt_tags[i].tagname)); + sprintf(p_control.mtt_tags[i].tagname, "%s", new_tagname); + break; + } + } + // free the sectors including the tag table + + // Save the changes to disk + fseek ( disk , (p_control.fsci->master_tag_records[0] * SECTOR_SIZE) , SEEK_SET ); + fwrite(p_control.mtt_tags, 1, sizeof(global_tag) * DEFAULT_MASTER_TAG_TABLE_SIZE, disk); + return 1; +} + +int lsfs_disk_rename_file(lsfs_file_id file_id, const char* new_filename) { + mif* mif_record = calloc(1, SECTOR_SIZE); + read_data_from_disk(file_id, mif_record); + + memset(mif_record->filename, 0, sizeof(mif_record->filename)); + sprintf(mif_record->filename, "%s", new_filename); + + time_t current_time; + time ( ¤t_time ); + + mif_record->last_modification_data = (uint64_t) current_time; + mif_record->last_access_date = (uint64_t) current_time; + + write_data_to_disk(file_id, mif_record); + free(mif_record); + return 1; +} + +int lsfs_disk_delete_file(lsfs_file_id file_id) { + mif* mif_record = calloc(1, SECTOR_SIZE); + read_data_from_disk(file_id, mif_record); + + for (int i = 0; i < MAX_TAGS_FOR_A_FILE; ++i) + { + if(mif_record->tags[i] == 0) { + break; + } + lsfs_disk_untag_file(mif_record->tags[i], file_id); + } + // TODO Delete/free all data sectors. + // Delete/free the mif record sector. + + free(mif_record); + return 1; +} + +int lsfs_disk_delete_tag(lsfs_tag_id tag_id) { + tag_record* tag_table = calloc(64, SECTOR_SIZE); + read_data_from_disk(tag_id, tag_table); + + for (int i = 0; i < MAX_TAGS_IN_TAG_TABLE; ++i) + { + if(tag_table[i].mif_record == 0) { + break; + } + lsfs_disk_untag_file(tag_id, tag_table[i].mif_record); + } + + + int truncate_table = 0; + + for (int i = 0; i < MAX_MASTER_TAGS; ++i) + { + if(p_control.mtt_tags[i].tag_table_index == tag_id) { + p_control.mtt_tags[i] = p_control.mtt_tags[i+1]; + truncate_table = 1; + printf("Tag deleted from master table - TagID: %lu\n", tag_id); + } + else if (truncate_table) { + p_control.mtt_tags[i] = p_control.mtt_tags[i+1]; + if (p_control.mtt_tags[i+1].tag_table_index == 0) { + break; + } + } + } + // free the sectors including the tag table + + // Save the changes to disk + fseek ( disk , (p_control.fsci->master_tag_records[0] * SECTOR_SIZE) , SEEK_SET ); + fwrite(p_control.mtt_tags, 1, sizeof(global_tag) * DEFAULT_MASTER_TAG_TABLE_SIZE, disk); + free(tag_table); + return 1; +} + +int lsfs_disk_tag_file(lsfs_tag_id tag_id, lsfs_file_id file_id) { + mif* mif_record = calloc(1, SECTOR_SIZE); + read_data_from_disk(file_id, mif_record); + + for (int i = 0; i < MAX_TAGS_FOR_A_FILE; ++i) + { + if(mif_record->tags[i] == 0) { + mif_record->tags[i] = tag_id; + break; + } + } + write_data_to_disk(file_id, mif_record); + free(mif_record); + + tag_record* tag_table = calloc(64, SECTOR_SIZE); + read_data_from_disk(tag_id, tag_table); + + for (int i = 0; i < MAX_TAGS_IN_TAG_TABLE; ++i) + { + if(tag_table[i].mif_record == 0) { + tag_table[i].mif_record = file_id; + printf("file tagged - TagID: %lu - FileID: %lu \n", tag_table[i].mif_record, file_id); + break; + } + } + write_data_to_disk(tag_id, tag_table); + free(tag_table); + return 1; +} + +int lsfs_disk_untag_file(lsfs_tag_id tag_id, lsfs_file_id file_id) { + mif* mif_record = calloc(1, SECTOR_SIZE); + read_data_from_disk(file_id, mif_record); + int truncate_table = 0; + + for (int i = 0; i < MAX_TAGS_FOR_A_FILE; ++i) + { + if(mif_record->tags[i] == tag_id) { + mif_record->tags[i] = mif_record->tags[i+1]; + truncate_table = 1; + printf("file untagged - TagID: %lu - FileID: %lu \n", tag_id, file_id); + } + else if (truncate_table) { + mif_record->tags[i] = mif_record->tags[i+1]; + if (mif_record->tags[i+1] == 0) { + break; + } + } + } + + time_t current_time; + time ( ¤t_time ); + + mif_record->last_modification_data = (uint64_t) current_time; + mif_record->last_access_date = (uint64_t) current_time; + + write_data_to_disk(file_id, mif_record); + free(mif_record); + + tag_record* tag_table = calloc(64, SECTOR_SIZE); + read_data_from_disk(tag_id, tag_table); + truncate_table = 0; + + for (int i = 0; i < MAX_TAGS_IN_TAG_TABLE; ++i) + { + if(tag_table[i].mif_record == file_id) { + tag_table[i].mif_record = tag_table[i+1].mif_record; + truncate_table = 1; + printf("file untagged - TagID: %lu - FileID: %lu \n", tag_table[i].mif_record, file_id); + } + else if (truncate_table) { + tag_table[i].mif_record = tag_table[i+1].mif_record; + if (tag_table[i+1].mif_record == 0) { + break; + } + } + } + write_data_to_disk(tag_id, tag_table); + free(tag_table); + return 1; +} + +lsfs_tag_id lsfs_disk_create_tag(char* tag_name, bool is_filename) { + /* Return ID of new tag, oterwise return 0 */ + lsfs_tag_id* free_sectors; + // Returns an array, with the sector numbers that is assignt to you + free_sectors = calloc(DEFAULT_TAG_TABLE_SIZE, sizeof(lsfs_tag_id)); + get_free_sectors(DEFAULT_TAG_TABLE_SIZE, free_sectors); // has to be freed + + // Insert tag in the master tag, table an set the pointer to the first of the tag table + int index_in_mtt = 0; + while(p_control.mtt_tags[index_in_mtt].tag_table_index != 0) { + //TODO also have to count if we enter next data section. + index_in_mtt++; + } + + + p_control.mtt_tags[index_in_mtt].tag_table_index = free_sectors[0]; + printf("%lu\n", free_sectors[0]); + sprintf(p_control.mtt_tags[index_in_mtt].tagname, "%s", tag_name); + p_control.mtt_tags[index_in_mtt].control_bits.is_filename = is_filename; + + tag_record new_tag[DEFAULT_TAG_TABLE_SIZE]; + memset(new_tag, 0, (DEFAULT_TAG_TABLE_SIZE * sizeof(tag_record))); + + //printf("Sector number: %lu, is assignt to you \n", (*free_sectors)); + //char* data = "red_file_1\nred_file_2\n"; + //char* sector_to_write = write_mechanism_new_buffer(data); + fseek ( disk , (p_control.fsci->master_tag_records[0] * SECTOR_SIZE) , SEEK_SET ); + fwrite(p_control.mtt_tags, 1, sizeof(global_tag) * DEFAULT_MASTER_TAG_TABLE_SIZE, disk); + + fseek ( disk , ((*free_sectors) * SECTOR_SIZE) , SEEK_SET ); + fwrite(new_tag, 1, DEFAULT_TAG_TABLE_SIZE * sizeof(tag_record), disk); + + //free(sector_to_write); + int return_value = free_sectors[0]; + free(free_sectors); + return return_value; +} + +int get_free_sectors(int num_sectors_needed, lsfs_sector_offset* output_array) { + /* + * TODO - WARNING + * This has to be a much better algoritm, to pick free sctors. + * We have to keep some bookeeping of what is free. + * Also if more sctors are claimed, we want them to be sequtive. + * This is just a naiv counter, just added more sectors to the file. + */ + + if (num_sectors_needed > 1) { + for (int i = 0; i < num_sectors_needed; ++i) + { + output_array[i] = p_control.fsci->next_free_sector; + p_control.fsci->next_free_sector++; + } + } + else { + output_array[0] = p_control.fsci->next_free_sector; + p_control.fsci->next_free_sector++; + } + printf("Sector %lu is assignt\n", output_array[0]); + write_data_to_disk(0, p_control.fsci); + return p_control.fsci->next_free_sector; +} + +int create_file_system() { + //char* sector_to_write; + // make default File System Control information (FSCI) + // first integer says how many pointers we got + // to master tag tables + // Second and forward is the pointers to the master Tag Tables + // we need the first number to allocate memory at one go. + int* zero_buffer; + FSCI fsci; + fsci.offset_on_disk = 1; + fsci.maximum_sectors_on_partition = 1048576; // Max 4GiB + fsci.next_free_sector = 257; + fsci.number_of_mtt = 1; + memset(fsci.master_tag_records, 0, 128); + fsci.master_tag_records[0] = 1; + + fseek ( disk , 0, SEEK_SET ); + fwrite(&fsci, 1, sizeof(fsci), disk); + zero_buffer = calloc(1, (4096 - sizeof(fsci))); + fwrite(zero_buffer, 1, (4096 - sizeof(fsci)), disk); + free(zero_buffer); + /* MASTER TAG TABLE */ + + global_tag mtt_tags[DEFAULT_MASTER_TAG_TABLE_SIZE]; + memset(mtt_tags, 0, (DEFAULT_MASTER_TAG_TABLE_SIZE * sizeof(global_tag))); + + fwrite(&mtt_tags, 1, sizeof(mtt_tags), disk); + zero_buffer = calloc(1, 16); + fwrite(zero_buffer, 1, 16, disk); + free(zero_buffer); + return 0; +} + +int lsfs_disk_load_disk() { + + // First we find the Mater Table. + fseek ( disk , 1 * SECTOR_SIZE, SEEK_SET ); + fread(p_control.mtt_tags, 1, sizeof(global_tag) * DEFAULT_MASTER_TAG_TABLE_SIZE , disk); + + // Now we can finde the FSCI data + fseek ( disk , 0, SEEK_SET ); + fread(p_control.fsci, 1, sizeof(FSCI), disk); + + return 1; +} + + +lsfs_tag_id lsfs_disk_create_file(char* filename, lsfs_tag_id* tags, void* file_data) { + + // create space for mif + mif new_file_data; + lsfs_tag_id return_id; + + + memset(new_file_data.filename, 0, sizeof(new_file_data.filename)); + sprintf(new_file_data.filename, "%s", filename); // remeber that the 260 bytes has to be a /0 terminator. // 260 because it pads to a full sector. + + printf("%s\n", new_file_data.filename); + new_file_data.owner_id = getuid(); + + lsfs_tag_id* index_to_mif_data; + index_to_mif_data = calloc(1, sizeof(lsfs_tag_id)); + get_free_sectors(1, index_to_mif_data); // has to be freed + + memset(new_file_data.tags, 0, (32 * sizeof(lsfs_tag_id))); + + new_file_data.file_size = 0; + + time_t current_time; + time ( ¤t_time ); + + new_file_data.creation_date = (uint64_t) current_time; + new_file_data.last_modification_data = (uint64_t) current_time; + new_file_data.last_access_date = (uint64_t) current_time; + + new_file_data.control_bits = 0; + memset(new_file_data.one_level_pointer_data, 0, (256 * sizeof(lsfs_sector_offset))); + memset(new_file_data.two_level_pointer_data, 0, (94 * sizeof(lsfs_sector_offset))); + memset(new_file_data.three_level_pointer_data, 0, (94 * sizeof(lsfs_sector_offset))); + get_free_sectors(1, new_file_data.one_level_pointer_data); + int actual_file_size = 0; + + new_file_data.file_size = actual_file_size; + fseek ( disk , index_to_mif_data[0] * SECTOR_SIZE, SEEK_SET ); + fwrite(&new_file_data, 1, SECTOR_SIZE, disk); + + printf("MIF written at sector: %lu\n", index_to_mif_data[0]); + printf("DATA written at sector: %lu\n", new_file_data.one_level_pointer_data[0]); + + int i = 0; + if (tags != NULL) { + while(tags[i] != 0) { + printf("A tag is found \n"); + lsfs_disk_tag_file(tags[i], index_to_mif_data[0]); + new_file_data.tags[i] = tags[i]; + i++; + } + } + + + return_id = index_to_mif_data[0]; + free(index_to_mif_data); + return return_id; +} + +int write_data_to_disk(lsfs_sector_offset index, void* data_to_write) { + fseek ( disk, (index * SECTOR_SIZE), SEEK_SET ); // SEEK_SET start offset at index 0 and move 1 * SECTOR_SIZE, and write here. + int written = fwrite(data_to_write, 1, SECTOR_SIZE, disk); + return written; +} + +int write_data_to_disk_off(lsfs_sector_offset index, void* data_to_write, int offset) { + fseek ( disk, (index * SECTOR_SIZE) + offset, SEEK_SET ); // SEEK_SET start offset at index 0 and move 1 * SECTOR_SIZE, and write here. + int written = fwrite(data_to_write, 1, SECTOR_SIZE, disk); + return written; +} + +int read_data_from_disk(lsfs_sector_offset index, void* data_buffer) { + fseek ( disk, (index * SECTOR_SIZE ), SEEK_SET ); // SEEK_SET start offset at index 0 and move 1 * SECTOR_SIZE, and write here. + int read = fread(data_buffer, 1, SECTOR_SIZE, disk); + return read; +} + +#endif diff --git a/lsfs_fuse b/lsfs_fuse new file mode 100755 index 0000000..8e528fe Binary files /dev/null and b/lsfs_fuse differ diff --git a/lsfs_fuse.c b/lsfs_fuse.c new file mode 100644 index 0000000..d77d7b0 --- /dev/null +++ b/lsfs_fuse.c @@ -0,0 +1,308 @@ +/* +TODO(jakob): we have a lot of memory leaks +TODO(jakob): handle multiple files with the same name!!! +*/ + +#include +#include +#include +#include +#include +#include + +#include "lsfs_disk_controller.h" + +int lsfs_getattr( const char *, struct stat * ); +int lsfs_mkdir(const char *path, mode_t mode); +int lsfs_mknod(const char *path, mode_t mode, dev_t device); +int lsfs_open( const char *, struct fuse_file_info * ); +int lsfs_read( const char *, char *, size_t, off_t, struct fuse_file_info * ); +int lsfs_readdir( const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info * ); +int lsfs_release(const char *path, struct fuse_file_info *fi); +int lsfs_rename(const char *from, const char *to); +int lsfs_rmdir(const char *path); +int lsfs_truncate(const char *path, off_t offset); +int lsfs_unlink(const char *); +int lsfs_write(const char *, const char *, size_t, off_t, struct fuse_file_info *); + +static inline int lsfs_utime_STUB(const char *path, struct utimbuf *buf) { + (void)path; + (void)buf; + return 0; +} + +static struct fuse_operations lsfs_oper = { + .getattr = lsfs_getattr, + .readdir = lsfs_readdir, + .mknod = lsfs_mknod, + .mkdir = lsfs_mkdir, + .link = NULL, + .unlink = lsfs_unlink, + .rmdir = lsfs_rmdir, + .truncate = lsfs_truncate, + .open = lsfs_open, + .read = lsfs_read, + .release = lsfs_release, + .write = lsfs_write, + .rename = NULL, + .utime = lsfs_utime_STUB, +}; + +int lsfs_mkdir(const char *path, mode_t mode) { + (void)mode; + + // Call to the disk controller make the dir + return 0; +} + + +int lsfs_rmdir(const char *path) { + + // call to the disk controller to remove a dir + + return 0; +} + +int lsfs_unlink(const char *path) { + + // remove / delete a file + + return 0; +} + +int lsfs_truncate(const char *path, off_t offset) { + (void)offset; + + + //found_file->modification_time = modification_time + + // Truncate a file + + return 0; +} + + +int lsfs_rename(const char *path, const char *to) { + (void)path; + (void)to; + return 0; +} + +int lsfs_getattr( const char *path, struct stat *stbuf ) { + int res = 0; + printf("getattr: (path=%s)\n", path); + + memset(stbuf, 0, sizeof(struct stat)); + if( strcmp( path, "/" ) == 0 ) { + stbuf->st_mode = S_IFDIR | 0755; + stbuf->st_nlink = 2; + } else if( strcmp( path, "/hello" ) == 0 ) { + stbuf->st_mode = S_IFREG | 0777; + stbuf->st_nlink = 1; + stbuf->st_size = 12; + } else + res = -ENOENT; + + return res; + // printf("getattr: (path=%s)\n", path); + + /*memset(stbuf, 0, sizeof(struct stat)); + + if( strcmp( path, "/" ) == 0 ) { + stbuf->st_mode = S_IFDIR | 0755; + stbuf->st_nlink = 3; + return res; + } + + lsfs_string_array split_path = lsfs_string_split_c(path, '/', false); + + lsfs_string filename = split_path.strings[split_path.length-1]; + + lsfs_tag *filename_tag = lsfs_hash_find(globals.tag_table, filename); + + if (filename_tag) { + if (filename_tag->is_filename) { + lsfs_file *found_file = lsfs_find_unique_file(filename_tag, split_path); + + if (found_file) { + if (found_file == &dummy_ambiguous_file) { + // stbuf->st_mode = S_IFDIR | 0755; // @Hardcode + // stbuf->st_nlink = 3; // @Hardcode + res = -ENOENT; + } + else { + stbuf->st_mode = S_IFREG | 0777; // @Hardcode + stbuf->st_nlink = 1; // @Hardcode + + stbuf->st_size = found_file->size; // @Hardcode + stbuf->st_uid = found_file->owner_id; + stbuf->st_gid = found_file->owner_id; + stbuf->st_atime = found_file->access_time; + stbuf->st_mtime = found_file->modification_time; + } + } + else { + res = -ENOENT; + } + } + else { + stbuf->st_mode = S_IFDIR | 0755; // @Hardcode + stbuf->st_nlink = 3; // @Hardcode + } + } + else { + res = -ENOENT; + } + + lsfs_destroy_string_array(split_path); + */ + //return res; +} + +int lsfs_write(const char *path, const char *content, size_t content_length, off_t offset_to_next_entry, struct fuse_file_info *file_info) { + (void) offset_to_next_entry; + //(void) file_info; + int res; + // printf("read: (path=%s)\n", path); + + time_t current_time; + time ( ¤t_time ); + + //res = lsfs_disk_write_data_to_file(((lsfs_file*) file_info->fh)->file_id, content_length, (void*) content); + + //((lsfs_file*) file_info->fh)->size += res; + //((lsfs_file*) file_info->fh)->access_time = current_time; + //((lsfs_file*) file_info->fh)->modification_time = current_time; + return res; +} + +int lsfs_readdir( const char *path, void *buf, fuse_fill_dir_t filler, off_t offset_to_next_entry, struct fuse_file_info *fi ) { + //(void) offset; + (void) fi; + printf("readdir: (path=%s)\n", path); + + if(strcmp(path, "/") != 0) + return -ENOENT; + + filler(buf, ".", NULL, 0); + filler(buf, "..", NULL, 0); + filler(buf, "hello", NULL, 0); + + return 0; +} + +//Permission +int lsfs_open( const char *path, struct fuse_file_info *fi ) { + // printf("open: (path=%s)\n", path); + // We can store a pinter in the *fi, this pointer can be used in both read and write. + // https://libfuse.github.io/doxygen/structfuse__operations.html + // printf("read: (path=%s)\n", path); + + /* + lsfs_string_array split_path = lsfs_string_split_c(path, '/', false); + + lsfs_string filename = split_path.strings[split_path.length-1]; + + lsfs_tag *filename_tag = lsfs_hash_find(globals.tag_table, filename); + + if (filename_tag) { + if (filename_tag->is_filename) { + lsfs_file *found_file = lsfs_find_unique_file(filename_tag, split_path); + + if (found_file) { + if (found_file != &dummy_ambiguous_file) { + //(void*) file_data_buffer = calloc(1, SECTOR_SIZE); + fi->fh = (uint64_t) found_file; + //lsfs_disk_read_data_from_file(found_file->file_id, (256*4096), buf); + } + } + } + } + + lsfs_destroy_string_array(split_path); + */ + return 0; +} + +int lsfs_read( const char *path, char *buf, size_t size, off_t offset_to_next_entry, struct fuse_file_info *fi ) { + // printf("read: (path=%s)\n", path); + + time_t current_time; + time ( ¤t_time ); + + //int res = lsfs_disk_read_data_from_file( ((lsfs_file*) fi->fh)->file_id, size, buf); + //((lsfs_file*) fi->fh)->access_time = current_time; + return 0; +} + +int lsfs_release(const char *path, struct fuse_file_info *fi) { + // printf("release: (path=%s)\n", path); + return 0; +} + +int lsfs_mknod(const char *path, mode_t mode, dev_t device) { + /*(void)mode; + (void)device; + int res = 0; + + lsfs_string_array split_path = lsfs_string_split_c(path, '/', false); + + lsfs_string filename = split_path.strings[split_path.length-1]; + if(filename.chars[0] == '@') { + res = -EINVAL; + goto end; + } + + lsfs_file *file = NULL; + + lsfs_tag *filename_tag = lsfs_hash_find(globals.tag_table, filename); + if (filename_tag) { + file = lsfs_find_unique_file(filename_tag, split_path); + if (file == &dummy_ambiguous_file) file = NULL; + } + + if (file) { + res = -EINVAL; + goto end; + } + + lsfs_file_id file_id = lsfs_disk_create_file(filename.chars, NULL, NULL ); + lsfs_set *tagset = lsfs_create_set(split_path.length - 1); + filename_tag = lsfs_get_or_create_tag(filename, true, true); + + file = lsfs_create_file(filename, file_id, tagset, filename_tag); + + lsfs_hash_table_index *index = malloc(sizeof(*index)); + *index = lsfs_hash_insert(globals.file_table, lsfs_create_id_string(file_id), file); + lsfs_set_insert(&filename_tag->fileset, file->file_id, index); + lsfs_disk_tag_file(filename_tag->tag_id, file->file_id); + + for (unsigned int i = 0; i < split_path.length - 1; ++i) { + lsfs_string tag_name = split_path.strings[i]; + lsfs_tag *tag = lsfs_get_or_create_tag(tag_name, true, false); + lsfs_tag_file(tag, file); + } + + lsfs_set_insert(&globals.all_files, file_id, index); + +end: + lsfs_destroy_string_array(split_path); + return res;*/ +} + +int main( int argc, char *argv[] ) { + + disk = fopen ( "~/Documents/github/SingOS/bin/SingOS.img" , "r+b" ); + p_control.fsci = malloc(sizeof(FSCI)); + p_control.master_table = malloc(sizeof(global_tag) * DEFAULT_MASTER_TAG_TABLE_SIZE); + lsfs_disk_load_disk(disk, &p_control); + + //tag_record *tag_table = calloc(1, SECTOR_SIZE); + //mif* mif_data = calloc(1, SECTOR_SIZE); + + //free(mif_data); + //free(tag_table); + //free(seen_file_ids); + + return fuse_main( argc, argv, &lsfs_oper ); +} diff --git a/lsfs_fuse.o b/lsfs_fuse.o new file mode 100644 index 0000000..779d9cf Binary files /dev/null and b/lsfs_fuse.o differ diff --git a/unload.sh b/unload.sh new file mode 100644 index 0000000..ec45713 --- /dev/null +++ b/unload.sh @@ -0,0 +1 @@ +fusermount -u lsfs_folder \ No newline at end of file