From 479c51ec52992743d4956b5590608e08af1a496e Mon Sep 17 00:00:00 2001 From: Matheus Date: Thu, 4 Aug 2022 19:31:10 -0300 Subject: [PATCH] Initrd parsing and more VFS funcs. Finished the initrd_parse() function for now and added vfs_open(), vfs_close() and vfs_write() --- src/fs/initrd.c | 33 ++++++++++++++++++++++--- src/fs/vfs.c | 53 ++++++++++++++++++++++++++++++++++++++-- src/include/kernel/vfs.h | 6 +++-- src/include/sys/stat.h | 4 +-- 4 files changed, 87 insertions(+), 9 deletions(-) diff --git a/src/fs/initrd.c b/src/fs/initrd.c index 2313cc07..cb4ac074 100644 --- a/src/fs/initrd.c +++ b/src/fs/initrd.c @@ -7,6 +7,14 @@ #define TAR_BLOCKSIZE 512 +#define TAR_FILE 0 +#define TAR_HARDLINK 1 +#define TAR_SYMLINK 2 +#define TAR_CHARDEV 3 +#define TAR_BLOCK 4 +#define TAR_DIR 5 +#define TAR_FIFO 6 + static volatile struct limine_module_request modreq = { .id = LIMINE_MODULE_REQUEST, .revision = 0 @@ -137,11 +145,30 @@ void initrd_parse(){ if(strncmp("ustar", entry.indicator, 5)) break; - - printf("NAME: %s SIZE: %lu\n", entry.name, entry.size); + void* datastart = addr + TAR_BLOCKSIZE; + addr += TAR_BLOCKSIZE + TAR_BLOCKSIZE * (entry.size / TAR_BLOCKSIZE) + (entry.size % TAR_BLOCKSIZE > 0 ? TAR_BLOCKSIZE : 0); - } + switch(entry.type){ + case TAR_FILE: + vfs_create(vfs_root(), entry.name, entry.mode); + break; + case TAR_DIR: + vfs_mkdir(vfs_root(), entry.name, entry.mode); + break; + default: + _panic("Unsupported file type in initrd!", 0); + } + + if(entry.type != TAR_FILE) continue; + + vnode_t *node; + vfs_open(&node, vfs_root(), entry.name); + vfs_write(&node, datastart, entry.size, 0); + vfs_close(&node); + + } + } diff --git a/src/fs/vfs.c b/src/fs/vfs.c index 0b3d22e4..98188c5c 100644 --- a/src/fs/vfs.c +++ b/src/fs/vfs.c @@ -14,6 +14,53 @@ static inline dirnode_t* mountpoint(dirnode_t* node){ return ret; } +int vfs_write(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 vfs_close(vnode_t* node){ + + vfs_releasenode(node); + + int status = 0; + + if(node->refcount == 0) + status = node->fs->calls->close(node); + + return status; +} + +int vfs_open(vnode_t** buff, dirnode_t* ref, char* path){ + + vnode_t* node; + + int res = vfs_resolvepath(&node, NULL, ref, path, NULL); + + if(res) + return res; + + vfs_acquirenode(node); + + *buff = node; + + return 0; + +} + int vfs_create(dirnode_t* ref, char* path, mode_t mode){ dirnode_t* parent = NULL; @@ -183,7 +230,8 @@ int vfs_resolvepath(vnode_t** result, dirnode_t** resultparent, dirnode_t* ref, if(!path[nameoffset]){ if(namebuff) strcpy(namebuff, name); - *resultparent = iterator; + if(resultparent) + *resultparent = iterator; } return status; } @@ -199,7 +247,8 @@ int vfs_resolvepath(vnode_t** result, dirnode_t** resultparent, dirnode_t* ref, if(namebuff) strcpy(namebuff, name); - *resultparent = iterator->vnode.parent; + if(resultparent) + *resultparent = iterator->vnode.parent; *result = (vnode_t*)iterator; return 0; diff --git a/src/include/kernel/vfs.h b/src/include/kernel/vfs.h index d156a12d..5e8920e5 100644 --- a/src/include/kernel/vfs.h +++ b/src/include/kernel/vfs.h @@ -52,16 +52,18 @@ typedef struct _fscalls_t { // create a new file // 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); } fscalls_t; int vfs_mount(dirnode_t* ref, char* device, char* mountpoint, char* fs, int mountflags, void* fsinfo); int vfs_umount(dirnode_t* ref, char* mountpoint); -int vfs_open(vnode_t* buf, dirnode_t* ref, char* path, int flags, mode_t mode); +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); void vfs_init(); dirnode_t* vfs_root(); diff --git a/src/include/sys/stat.h b/src/include/sys/stat.h index d4d50179..465f4b76 100644 --- a/src/include/sys/stat.h +++ b/src/include/sys/stat.h @@ -8,8 +8,8 @@ #define TYPE_DIR 4 #define TYPE_BLOCKDEV 6 #define TYPE_REGULAR 8 -#define TYPE_IFLNK 10 -#define TYPE_IFSOCK 12 +#define TYPE_LINK 10 +#define TYPE_SOCKET 12 #define GETMODE(m) (0xFFF & m) #define GETTYPE(m) ((m >> 12) & 0xF)