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