You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
324 lines
9.3 KiB
324 lines
9.3 KiB
/*
|
|
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;
|
|
lsfs_file *found_file = calloc(1, sizeof(lsfs_file));
|
|
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(lsfs_disk_getattr(found_file, path)) {
|
|
stbuf->st_mode = S_IFREG | 0777; // @Hardcode
|
|
stbuf->st_nlink = 1; // @Hardcode
|
|
stbuf->st_size = found_file->size;
|
|
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;
|
|
//free(found_file);
|
|
}
|
|
else {
|
|
res = -ENOENT;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*else {
|
|
if (lsfs_disk_getattr(found_file, path)) {
|
|
stbuf->st_mode = S_IFREG | 0777; // @Hardcode
|
|
stbuf->st_nlink = 1; // @Hardcode
|
|
stbuf->st_size = found_file->size;
|
|
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;
|
|
free(found_file);
|
|
}
|
|
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);
|
|
|
|
int i = 0;
|
|
while(strcmp( "", p_control.master_table[i].filename ) != 0) {
|
|
filler(buf, p_control.master_table[i].filename, NULL, 0);
|
|
i++;
|
|
}
|
|
|
|
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_file *found_file = calloc(1, sizeof(lsfs_file));
|
|
|
|
if (lsfs_disk_getattr(found_file, path)) {
|
|
fi->fh = (uint64_t) found_file;
|
|
}
|
|
|
|
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 res;
|
|
}
|
|
|
|
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[] ) {
|
|
// "/home/rhodez-x/Documents/github/SingOS/bin/SingOS.img"
|
|
disk = fopen ("/home/rhodez-x/Documents/github/SingOS/bin/SingOS.img", "r+b");
|
|
p_control.fsci = malloc(sizeof(FSCI));
|
|
p_control.master_table = malloc(sizeof(table_entry) * DEFAULT_MASTER_TABLE_SIZE);
|
|
lsfs_disk_load_disk();
|
|
|
|
//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 );
|
|
}
|
|
|