From 8018ecd27411bd195c612b9e3bc30c7776145dbd Mon Sep 17 00:00:00 2001 From: Enrico Fraccaroli Date: Thu, 23 Dec 2021 17:36:23 +0100 Subject: [PATCH] [WIP] Start implementing creat. --- mentos/src/fs/ext2.c | 63 +++++++++++++--------------------------- mentos/src/kernel.c | 5 ++++ mentos/src/klib/libgen.c | 6 ++-- 3 files changed, 28 insertions(+), 46 deletions(-) diff --git a/mentos/src/fs/ext2.c b/mentos/src/fs/ext2.c index 50f21f5..176aa1e 100644 --- a/mentos/src/fs/ext2.c +++ b/mentos/src/fs/ext2.c @@ -1615,7 +1615,7 @@ static int ext2_allocate_direntry(ext2_filesystem_t *fs, vfs_file_t *parent, cha /// @param name the name of the entry we are looking for. /// @param search the output variable where we save the info about the entry. /// @return 0 on success, -1 on failure. -static int ext2_find_entry(ext2_filesystem_t *fs, ino_t ino, const char *name, ext2_direntry_search_t *search) +static int ext2_find_direntry(ext2_filesystem_t *fs, ino_t ino, const char *name, ext2_direntry_search_t *search) { if (fs == NULL) { pr_err("You provided a NULL filesystem.\n"); @@ -1633,7 +1633,7 @@ static int ext2_find_entry(ext2_filesystem_t *fs, ino_t ino, const char *name, e pr_err("You provided a NULL direntry.\n"); return -1; } - pr_debug("ext2_find_entry(ino: %d, name: \"%s\")\n", ino, name); + pr_debug("ext2_find_direntry(ino: %d, name: \"%s\")\n", ino, name); // Allocate the cache. uint8_t *cache = kmem_cache_alloc(fs->ext2_buffer_cache, GFP_KERNEL); // Clean the cache. @@ -1660,16 +1660,19 @@ static int ext2_find_entry(ext2_filesystem_t *fs, ino_t ino, const char *name, e // Check if we have found the entry. if (it.direntry == NULL) goto free_cache_return_error; - pr_debug("ext2_find_entry(ino: %d, name: \"%s\") -> (ino: %d, name: \"%s\")\n", - ino, name, it.direntry->inode, it.direntry->name); // Copy the direntry. memcpy(search->direntry, it.direntry, sizeof(ext2_dirent_t)); + // Close the name. + search->direntry->name[search->direntry->name_len] = 0; // Copy the index of the block containing the direntry. search->block_index = it.block_index; // Copy the offset of the direntry inside the block. search->block_offset = it.block_offset; // Free the cache. kmem_cache_free(cache); + + pr_debug("ext2_find_direntry(ino: %d, name: \"%s\") -> (ino: %d, name: \"%s\")\n", + ino, name, search->direntry->inode, search->direntry->name); return 0; free_cache_return_error: // Free the cache. @@ -1710,12 +1713,12 @@ static int ext2_resolve_path(vfs_file_t *directory, char *path, ext2_direntry_se } // If the path is `/`. if (strcmp(path, "/") == 0) - return ext2_find_entry(fs, directory->ino, path, search); + return ext2_find_direntry(fs, directory->ino, path, search); ino_t ino = directory->ino; char *tmp_path = strdup(path); char *token = strtok(tmp_path, "/"); while (token) { - if (!ext2_find_entry(fs, ino, token, search)) { + if (!ext2_find_direntry(fs, ino, token, search)) { ino = search->direntry->inode; } else { memset(search->direntry, 0, sizeof(ext2_dirent_t)); @@ -2012,47 +2015,21 @@ static vfs_file_t *ext2_open(const char *path, int flags, mode_t mode) } else { // If we need to create it, it's ok if it does not exist. if (bitmask_check(flags, O_CREAT)) { - pr_warning("We want to create a new file at `%s`.\n", path); - pr_warning("The inode of the parent is `%d`.\n", search.parent_inode); -#if 0 - // Prepare the structure for the inode. - ext2_inode_t parent_inode; - memset(&parent_inode, 0, sizeof(ext2_inode_t)); - // Get the inode associated with the directory entry. - if (ext2_read_inode(fs, &parent_inode, search.parent_inode) == -1) { - pr_err("Failed to read the inode of the parent `%d`.\n", search.parent_inode); - return NULL; - } - // Search for the parent VFS file. - vfs_file_t *parent = ext2_find_vfs_file_with_inode(fs, search.parent_inode); - if (parent == NULL) { - // Allocate the memory for the parent file. - parent = kmem_cache_alloc(vfs_file_cache, GFP_KERNEL); - if (parent == NULL) { - pr_err("Failed to allocate memory for the parent.\n"); - return NULL; + // Get the name of the directory. + char *parent_path = dirname(path); + if (strcmp(parent_path, path)) { + // Get the parent VFS node. + vfs_file_t *parent = ext2_open(parent_path, O_RDONLY, 0); + if (parent) { + // Create the file. + ext2_creat(parent, basename(path), mode); + // Close the parent directory. + ext2_close(parent); } - if (ext2_init_vfs_file(fs, &parent_inode, &direntry, parent) == -1) { - pr_err("Failed to properly set the VFS file.\n"); - kmem_cache_free(parent); - return NULL; - } - // Add the vfs_file to the list of associated files. - list_head_add_tail(&parent->siblings, &fs->opened_files); - // Create the file. - vfs_file_t *new_file = ext2_creat(parent, basename(path), mode); - // Remove the parent from the list of opened VFS files. - list_head_del(&parent->siblings); - // Destroy the VFS file. - kmem_cache_free(parent); - return new_file; - } else { - return ext2_creat(parent, basename(path), mode); } -#endif return NULL; } else { - pr_err("Failed to resolve absolute path `%s`.\n", absolute_path); + pr_err("The file does not exist `%s`.\n", absolute_path); return NULL; } } diff --git a/mentos/src/kernel.c b/mentos/src/kernel.c index e131892..b66db4d 100644 --- a/mentos/src/kernel.c +++ b/mentos/src/kernel.c @@ -34,6 +34,7 @@ #include "assert.h" #include "io/vga/vga.h" #include "string.h" +#include "fcntl.h" /// Describe start address of grub multiboot modules. char *module_start[MAX_MODULES]; @@ -349,6 +350,10 @@ int kmain(boot_info_t *boot_informations) } print_ok(); + vfs_file_t *file = vfs_open("/home/test.txt", O_CREAT | O_EXCL, 0); + + while (true) {} + // We have completed the booting procedure. pr_notice("Booting done, jumping into init process.\n"); // Print the welcome message. diff --git a/mentos/src/klib/libgen.c b/mentos/src/klib/libgen.c index 10283c6..c0f642d 100644 --- a/mentos/src/klib/libgen.c +++ b/mentos/src/klib/libgen.c @@ -87,10 +87,10 @@ char *realpath(const char *path, char *resolved) memset(abspath, '\0', PATH_MAX); int remaining; if (path[0] != '/') { - // Get the current task. + // Get the working directory of the current task. sys_getcwd(abspath, PATH_MAX); - // Check the current task. - assert((strlen(abspath) > 0) && "There is no current task."); + // Check the absolute path. + assert((strlen(abspath) > 0) && "Current working directory is set."); // Check that the current working directory is an absolute path. assert((abspath[0] == '/') && "Current working directory is not an absolute path."); // Count the remaining space in the absolute path.