mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
add tmpfs writing, vfs node tree dumping and fix some stupid issues
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user