add tmpfs writing, vfs node tree dumping and fix some stupid issues

This commit is contained in:
Matheus
2022-08-04 20:18:57 -03:00
parent 479c51ec52
commit ea8f21fb71
5 changed files with 104 additions and 19 deletions
+1 -1
View File
@@ -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)
+6 -2
View File
@@ -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);
}
+47 -6
View File
@@ -2,6 +2,8 @@
#include <kernel/vfs.h>
#include <kernel/alloc.h>
#include <arch/mmu.h>
#include <kernel/pmm.h>
#include <string.h>
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
};
+48 -8
View File
@@ -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;
}
+2 -2
View File
@@ -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();