From ea8f21fb711d5168668f37e890a3bd33fdcefc42 Mon Sep 17 00:00:00 2001 From: Matheus Date: Thu, 4 Aug 2022 20:18:57 -0300 Subject: [PATCH] add tmpfs writing, vfs node tree dumping and fix some stupid issues --- Makefile | 2 +- src/fs/initrd.c | 8 ++++-- src/fs/tmpfs.c | 53 ++++++++++++++++++++++++++++++++----- src/fs/vfs.c | 56 ++++++++++++++++++++++++++++++++++------ src/include/kernel/vfs.h | 4 +-- 5 files changed, 104 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 123b0e4b..b8130359 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ $(KERNEL): srcdir $(KERNELSRCDEPS) kernel.ld mkdir -p $(ISO) $(CC) $(LDFLAGS) -o $@ $(call rwildcard,bin,*.o) -$(INITRD): $(call rwildcard,initrd,*) +$(INITRD): initrd cd initrd;tar -cf $(INITRD) * sysdisk.iso: $(ISO) $(INITRD) diff --git a/src/fs/initrd.c b/src/fs/initrd.c index cb4ac074..218af213 100644 --- a/src/fs/initrd.c +++ b/src/fs/initrd.c @@ -165,9 +165,13 @@ void initrd_parse(){ if(entry.type != TAR_FILE) continue; vnode_t *node; + int error; vfs_open(&node, vfs_root(), entry.name); - vfs_write(&node, datastart, entry.size, 0); - vfs_close(&node); + if(vfs_write(&error, node, datastart, entry.size, 0) == -1){ + printf("WRITE ERROR %lu\n", error); + _panic("Failed to write from initrd", 0); +} + vfs_close(node); } diff --git a/src/fs/tmpfs.c b/src/fs/tmpfs.c index df5f0fc3..e816793b 100644 --- a/src/fs/tmpfs.c +++ b/src/fs/tmpfs.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include static int tmpfs_mount(dirnode_t* mountpoint, vnode_t* device, int mountflags, void* fsinfo){ @@ -23,6 +25,34 @@ static int tmpfs_mount(dirnode_t* mountpoint, vnode_t* device, int mountflags, v return 0; } +static int tmpfs_write(int* error, vnode_t* node, void* buff, size_t count, size_t offset){ + + // TODO use virtual memory + + size_t targetpage = (count + offset) / PAGE_SIZE; + + if(node->st.st_blocks <= targetpage){ + void* new = pmm_hhdmalloc(targetpage+1); + if(!new){ + *error = ENOMEM; + return -1; + }; + memcpy(new, node->fsdata, node->st.st_size); + pmm_free(node->fsdata, node->st.st_size / PAGE_SIZE + 1); + node->fsdata = new; + node->st.st_blocks = targetpage+1; + node->st.st_size = count + offset; + } + + memcpy(node->fsdata + offset, buff, count); + + if(offset + count > node->st.st_size) + node->st.st_size = offset + count; + + *error = 0; + return count; +} + static int tmpfs_unmount(fs_t* fs) UNIMPLEMENTED static int tmpfs_open(dirnode_t* parent, char* name) UNIMPLEMENTED static int tmpfs_close(vnode_t* node) UNIMPLEMENTED @@ -49,27 +79,38 @@ static int tmpfs_mkdir(dirnode_t* parent, char* name, mode_t mode){ } static int tmpfs_create(dirnode_t* parent, char* name, mode_t mode){ - - vnode_t* node = vfs_newnode(name, parent->vnode.fs, NULL); - - if(!node) + + // TODO use virtual memory + void* firstpage = pmm_hhdmalloc(1); + + if(!firstpage) return ENOMEM; + + vnode_t* node = vfs_newnode(name, parent->vnode.fs, NULL); + + if(!node){ + pmm_free(firstpage, 1); + return ENOMEM; + } if(!hashtable_insert(&parent->children, name, node)){ + pmm_free(firstpage, 1); vfs_destroynode(node); return ENOMEM; } node->parent = parent; + node->fsdata = firstpage; stat* st = &node->st; - st->st_mode = MAKETYPE(TYPE_DIR) | GETMODE(mode); st->st_blksize = PAGE_SIZE; + st->st_blocks = 1; + return 0; } static fscalls_t funcs = { - tmpfs_mount, tmpfs_unmount, tmpfs_open, tmpfs_close, tmpfs_mkdir, tmpfs_create + tmpfs_mount, tmpfs_unmount, tmpfs_open, tmpfs_close, tmpfs_mkdir, tmpfs_create, tmpfs_write }; diff --git a/src/fs/vfs.c b/src/fs/vfs.c index 98188c5c..fcd61886 100644 --- a/src/fs/vfs.c +++ b/src/fs/vfs.c @@ -14,21 +14,61 @@ static inline dirnode_t* mountpoint(dirnode_t* node){ return ret; } -int vfs_write(vnode_t* node, void* buff, size_t count, size_t offset){ +void vfs_debugdumptree(dirnode_t* node, size_t depth, size_t maxdepth){ - int type = GETTYPE(node->st.st_mode); + if(depth > maxdepth) + return; + + printf("Directory node: %s Children: ", node->vnode.name); + // print all children first + + node = mountpoint(node); + + for(size_t i = 0; i < node->children.size; ++i){ + hashtableentry* entry = &node->children.entries[i]; + + while(entry && entry->key){ + printf("%s ", entry->key); + entry = entry->next; + } + + } + // now recurse into directories + + printf("\n"); + + for(size_t i = 0; i < node->children.size; ++i){ + hashtableentry* entry = &node->children.entries[i]; + + while(entry && entry->val){ + vnode_t* chnode = entry->val; + + if(GETTYPE(chnode->st.st_mode) == TYPE_DIR) + vfs_debugdumptree((dirnode_t*)chnode, depth + 1, maxdepth); + entry = entry->next; + } + + + } + + +} + +int vfs_write(int* error, vnode_t* node, void* buff, size_t count, size_t offset){ + + + int type = GETTYPE(node->st.st_mode); + if(type == TYPE_DIR || type == TYPE_LINK) return EINVAL; if(type == TYPE_BLOCKDEV || type == TYPE_CHARDEV) return ENOSYS; // TODO change this when the device manager is implemented :) - - - int status = node->fs->calls->write(node, buff, count, offset); - - - return 0; + + int writecount = node->fs->calls->write(error, node, buff, count, offset); + + return writecount; } diff --git a/src/include/kernel/vfs.h b/src/include/kernel/vfs.h index 5e8920e5..8ee86b4f 100644 --- a/src/include/kernel/vfs.h +++ b/src/include/kernel/vfs.h @@ -53,7 +53,7 @@ typedef struct _fscalls_t { // args: parent, name, mode int (*create)(dirnode_t* parent, char* name, mode_t mode); // write to a file - int (*write)(vnode_t* node, void* buff, size_t count, size_t offset); + int (*write)(int* error, vnode_t* node, void* buff, size_t count, size_t offset); } fscalls_t; @@ -63,7 +63,7 @@ int vfs_open(vnode_t** buf, dirnode_t* ref, char* path); int vfs_close(vnode_t* node); int vfs_mkdir(dirnode_t* ref, char* path, mode_t mode); int vfs_create(dirnode_t* ref, char* path, mode_t mode); -int vfs_write(vnode_t* node, void* buff, size_t count, size_t offset); +int vfs_write(int* error, vnode_t* node, void* buff, size_t count, size_t offset); void vfs_init(); dirnode_t* vfs_root();