[WIP] Start implementing creat.

This commit is contained in:
Enrico Fraccaroli
2021-12-23 17:36:23 +01:00
parent 913e7bf0b7
commit 8018ecd274
3 changed files with 28 additions and 46 deletions
+20 -43
View File
@@ -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;
}
}
+5
View File
@@ -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.
+3 -3
View File
@@ -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.