From ed9a51dcdbb88939202fbe1fc4d4de2615c5085f Mon Sep 17 00:00:00 2001 From: Johan Manuel Date: Mon, 16 Nov 2020 09:57:17 +0100 Subject: [PATCH] Change how dot folder entries are handled They're not pulled from the fs anymore, because it'd be a pain to implement them in "fake" file systems that aren't really about files, things like lists of processes, stuff like that. --- kernel/include/kernel/fs.h | 4 +- kernel/src/kernel.c | 5 ++- kernel/src/misc/ext2.c | 9 ++++ kernel/src/misc/fs.c | 91 +++++++++++++++----------------------- kernel/src/misc/wm/wm.c | 13 +++++- kernel/src/sys/syscall.c | 3 ++ libc/src/math.c | 2 +- modules/src/terminal.c | 2 +- 8 files changed, 68 insertions(+), 61 deletions(-) diff --git a/kernel/include/kernel/fs.h b/kernel/include/kernel/fs.h index 0d43cd0..058571d 100644 --- a/kernel/include/kernel/fs.h +++ b/kernel/include/kernel/fs.h @@ -44,6 +44,7 @@ typedef struct fs_t { /* TODO: require null termination of entries */ sos_directory_entry_t* (*readdir)(struct fs_t*, uint32_t, uint32_t); inode_t* (*get_fs_inode)(struct fs_t*, uint32_t); + int32_t (*close)(fs_t*, uint32_t) } fs_t; typedef inode_t* (*fs_get_fs_inode_t)(struct fs_t*, uint32_t); @@ -52,6 +53,7 @@ typedef uint32_t (*fs_append_t)(struct fs_t*, uint32_t, uint8_t*, uint32_t); typedef uint32_t (*fs_read_t)(struct fs_t*, uint32_t, uint32_t, uint8_t*, uint32_t); typedef int32_t (*fs_unlink_t)(struct fs_t*, uint32_t, uint32_t); typedef uint32_t (*fs_create_t)(struct fs_t*, const char*, uint32_t, uint32_t); +typedef int32_t (*fs_close_t)(struct fs_t*, uint32_t); void init_fs(fs_t* fs); void fs_mount(const char* mount_point, fs_t* fs); @@ -59,7 +61,7 @@ char* fs_normalize_path(const char* p); inode_t* fs_open(const char* path, uint32_t mode); uint32_t fs_mkdir(const char* path, uint32_t mode); int32_t fs_unlink(const char* path); -void fs_close(inode_t* in); +int32_t fs_close(inode_t* in); uint32_t fs_read(inode_t* in, uint32_t offset, uint8_t* buf, uint32_t size); uint32_t fs_write(inode_t* in, uint8_t* buf, uint32_t size); uint32_t fs_readdir(inode_t* in, uint32_t offset, sos_directory_entry_t* d_ent, uint32_t size); \ No newline at end of file diff --git a/kernel/src/kernel.c b/kernel/src/kernel.c index 21b3197..b89742f 100644 --- a/kernel/src/kernel.c +++ b/kernel/src/kernel.c @@ -50,8 +50,6 @@ void kernel_main(multiboot_t* boot, uint32_t magic) { init_ps2(); init_timer(); - init_wm(); - init_proc(); printk("loading modules"); @@ -80,6 +78,9 @@ void kernel_main(multiboot_t* boot, uint32_t magic) { printk("ignored module: %s", module_name); } + init_wm(); + init_proc(); + proc_exec("/background", NULL); proc_exec("/terminal", NULL); diff --git a/kernel/src/misc/ext2.c b/kernel/src/misc/ext2.c index 9842031..b03af5e 100644 --- a/kernel/src/misc/ext2.c +++ b/kernel/src/misc/ext2.c @@ -160,6 +160,7 @@ uint32_t ext2_read(ext2_fs_t* fs, uint32_t inode, uint32_t offset, uint8_t* buf, uint32_t ext2_append(ext2_fs_t* fs, uint32_t inode, uint8_t* data, uint32_t size); sos_directory_entry_t* ext2_readdir(ext2_fs_t* fs, uint32_t inode, uint32_t offset); inode_t* ext2_get_fs_inode(ext2_fs_t* fs, uint32_t inode); +int32_t ext2_close(fs_t* fs, uint32_t ino); static void read_block(ext2_fs_t* fs, uint32_t block, uint8_t* buf); static void write_block(ext2_fs_t* fs, uint32_t block, uint8_t* buf); @@ -208,6 +209,7 @@ fs_t* init_ext2(uint8_t* data, uint32_t len) { e2fs->fs.read = (fs_read_t) ext2_read; e2fs->fs.readdir = (fs_readdir_t) ext2_readdir; e2fs->fs.unlink = (fs_unlink_t) ext2_unlink; + e2fs->fs.close = (fs_close_t) ext2_close; e2fs->fs.uid = e2fs->sb->id[0]; e2fs->fs.root = (folder_inode_t*) ext2_get_fs_inode(e2fs, EXT2_ROOT_INODE); @@ -407,6 +409,13 @@ inode_t* ext2_get_fs_inode(ext2_fs_t* fs, uint32_t inode) { return fs_in; } +int32_t ext2_close(fs_t* fs, uint32_t ino) { + UNUSED(fs); + UNUSED(ino); + + return 0; +} + /* Utility functions */ /* Reads the content of the given block. diff --git a/kernel/src/misc/fs.c b/kernel/src/misc/fs.c index bbb0772..4bdb8f9 100644 --- a/kernel/src/misc/fs.c +++ b/kernel/src/misc/fs.c @@ -58,21 +58,28 @@ void fs_build_tree_level(folder_inode_t* inode, inode_t* parent) { sos_directory_entry_t* dent = NULL; uint32_t offset = 0; + /* Add "." and ".." ourselves, don't trust the fs */ + tnode_t* tn = kmalloc(sizeof(tnode_t)); + tn->inode = (inode_t*) inode; + tn->name = strdup("."); + list_add(&inode->subfolders, tn); + + tn = kmalloc(sizeof(tnode_t)); + tn->inode = parent; + tn->name = strdup(".."); + list_add(&inode->subfolders, tn); + + /* Add the rest of the entries */ while ((dent = FS(inode)->readdir(FS(inode), inode->ino.inode_no, offset)) != NULL && dent->type != DENT_INVALID) { offset += dent->entry_size; - tnode_t* tn = kmalloc(sizeof(tnode_t)); - tn->name = strndup(dent->name, dent->name_len_low); - - if (!strncmp(dent->name, ".", dent->name_len_low)) { - tn->inode = (inode_t*) inode; - } else if (!strncmp(dent->name, "..", dent->name_len_low)) { - tn->inode = parent; - } else { + if (strncmp(dent->name, ".", dent->name_len_low) && strncmp(dent->name, "..", dent->name_len_low)) { + tn = kmalloc(sizeof(tnode_t)); + tn->name = strndup(dent->name, dent->name_len_low); tn->inode = FS(inode)->get_fs_inode(FS(inode), dent->inode); + list_add(dent->type == DENT_FILE ? &inode->subfiles : &inode->subfolders, tn); } - list_add(dent->type == DENT_FILE ? &inode->subfiles : &inode->subfolders, tn); kfree(dent); } @@ -86,7 +93,6 @@ void fs_build_tree_level(folder_inode_t* inode, inode_t* parent) { * TODO: prevent creating duplicate entries. */ inode_t* fs_open(const char* path, uint32_t flags) { - // printk("open: %s, creat %d, creatd %d", path, (flags & O_CREAT) != 0, (flags & O_CREATD) != 0); char* npath = fs_normalize_path(path); if (!strcmp(npath, "/")) { @@ -162,7 +168,7 @@ inode_t* fs_open(const char* path, uint32_t flags) { * The first filesystem can be mounted at "/". */ void fs_mount(const char* mount_point, fs_t* fs) { - // Special case for the first filesystem mounted + /* Special case for the first filesystem mounted */ if (!root && !strcmp(mount_point, "/")) { root = kmalloc(sizeof(tnode_t)); root->inode = (inode_t*) fs->root; @@ -170,6 +176,7 @@ void fs_mount(const char* mount_point, fs_t* fs) { return; } + /* Check the mount point's validity */ folder_inode_t* mnt_in = (folder_inode_t*) fs_open(mount_point, O_RDONLY); if (mnt_in->ino.type != DENT_DIRECTORY) { @@ -188,6 +195,7 @@ void fs_mount(const char* mount_point, fs_t* fs) { return; } + /* Empty its "." and ".." entries */ while (!list_empty(&mnt_in->subfolders)) { tnode_t* tn = list_first_entry(&mnt_in->subfolders, tnode_t); kfree(tn->name); @@ -202,32 +210,6 @@ void fs_mount(const char* mount_point, fs_t* fs) { mnt_in->subfolders = LIST_HEAD_INIT(mnt_in->subfolders); } -/* From an inode number, finds the corresponding inode_t*. - */ -inode_t* fs_find_inode(folder_inode_t* parent, uint32_t inode, uint32_t fs_no) { - tnode_t* tn; - - list_for_each_entry(tn, &parent->subfiles) { - if (tn->inode->inode_no == inode && tn->inode->fs->uid == fs_no) { - return tn->inode; - } - } - - list_for_each_entry(tn, &parent->subfolders) { - if (tn->inode->inode_no == inode && tn->inode->fs->uid == fs_no) { - return tn->inode; - } - - inode_t* subresult = fs_find_inode((folder_inode_t*) tn->inode, inode, fs_no); - - if (subresult) { - return subresult; - } - } - - return NULL; -} - uint32_t fs_mkdir(const char* path, uint32_t mode) { UNUSED(mode); @@ -238,35 +220,34 @@ uint32_t fs_mkdir(const char* path, uint32_t mode) { inode_t* in = fs_open(path, O_CREATD); - if (!in) { - return FS_INVALID_INODE; - } - - return in->inode_no; + return in ? in->inode_no : FS_INVALID_INODE; } int32_t fs_unlink(const char* path) { + /* Check that we're unlinking a file */ char* npath = fs_normalize_path(path); - folder_inode_t* d_in = (folder_inode_t*) fs_open(dirname(npath), O_RDONLY); inode_t* in = fs_open(npath, O_RDONLY); kfree(npath); - if (in->type == DENT_DIRECTORY) { + if (!d_in || !in || in->type != DENT_FILE) { return -1; } - if (!d_in || !in) { + /* Ask the filesystem to unlink that inode */ + int32_t ret = FS(d_in)->unlink(FS(d_in), d_in->ino.inode_no, in->inode_no); + + if (ret == -1) { return -1; } - // Update the cache + /* Prune it from the tree */ list_t* iter; - tnode_t* ent; - list_for_each(iter, ent, &d_in->subfiles) { - if (ent->inode->inode_no == in->inode_no) { - kfree(ent->name); - kfree(ent); + tnode_t* tn; + list_for_each(iter, tn, &d_in->subfiles) { + if (tn->inode->inode_no == in->inode_no) { + kfree(tn->name); + kfree(tn); if (--in->hardlinks == 0) { kfree(in); @@ -277,13 +258,13 @@ int32_t fs_unlink(const char* path) { } } - return FS(d_in)->unlink(FS(d_in), d_in->ino.inode_no, in->inode_no); + return 0; } -/* A process has released its grip on a file: TODO something. +/* A process has released its grip on a file: notify the fs. */ -void fs_close(inode_t* in) { - UNUSED(in); +int32_t fs_close(inode_t* in) { + return FS(in)->close(FS(in), in->inode_no); } uint32_t fs_read(inode_t* in, uint32_t offset, uint8_t* buf, uint32_t size) { diff --git a/kernel/src/misc/wm/wm.c b/kernel/src/misc/wm/wm.c index 4b238c2..0f95dbf 100644 --- a/kernel/src/misc/wm/wm.c +++ b/kernel/src/misc/wm/wm.c @@ -3,6 +3,8 @@ #include #include +#include + #include #include #include @@ -65,6 +67,10 @@ uint32_t wm_open_window(fb_t* buff, uint32_t flags) { wm_assign_z_orders(); wm_raise_window(win); + char str[20] = "/wm/"; + itoa(win->id, str+strlen(str), 10); + fs_open(str, O_CREAT); + return win->id; } @@ -84,6 +90,10 @@ void wm_close_window(uint32_t win_id) { } wm_refresh_partial(rect); + + char str[20] = "/wm/"; + itoa(win_id, str+strlen(str), 10); + fs_unlink(str); } else { printke("close: failed to find window of id %d", win_id); } @@ -559,4 +569,5 @@ void wm_kbd_callback(kbd_event_t event) { return; } } - } \ No newline at end of file + } +} \ No newline at end of file diff --git a/kernel/src/sys/syscall.c b/kernel/src/sys/syscall.c index c9b90f3..e13a0bb 100644 --- a/kernel/src/sys/syscall.c +++ b/kernel/src/sys/syscall.c @@ -116,6 +116,9 @@ static void syscall_wm(registers_t* regs) { case WM_CMD_OPEN: { wm_param_open_t* param = (wm_param_open_t*) regs->ecx; regs->eax = wm_open_window(param->fb, param->flags); + char str[20] = "/wm/"; + itoa(regs->eax, str+strlen(str), 10); + proc_open(str, O_RDONLY); } break; case WM_CMD_CLOSE: wm_close_window(regs->ecx); diff --git a/libc/src/math.c b/libc/src/math.c index c17f81f..ae723e8 100644 --- a/libc/src/math.c +++ b/libc/src/math.c @@ -90,7 +90,7 @@ double pow(double x, double y) { } int powi(int x, int y) { - int n = 1; + unsigned int n = 1; while (y--) { n *= x; diff --git a/modules/src/terminal.c b/modules/src/terminal.c index 261421a..38b096a 100644 --- a/modules/src/terminal.c +++ b/modules/src/terminal.c @@ -114,7 +114,7 @@ int main() { str_free(text_buf); str_free(input_buf); - snow_close_window(win); + // snow_close_window(win); return 0; }