Kernel: Make mkdir() accessible to userspace

This commit is contained in:
apio 2022-10-16 17:22:12 +02:00
parent 18fbccafb7
commit d2e2883a79
7 changed files with 63 additions and 20 deletions

View File

@ -6,7 +6,11 @@
#define EBADF 9
#define ENOMEM 12
#define EFAULT 14
#define EEXIST 17
#define ENOTDIR 20
#define EISDIR 21
#define EINVAL 22
#define EMFILE 24
#define ENOSPC 28
#define ENOSYS 38
#define ENOTSUP 95

View File

@ -18,6 +18,7 @@
#define SYS_fcntl 13
#define SYS_mprotect 14
#define SYS_clock 15
#define SYS_mkdir 17 // 16 is reserved for fork(), which is WIP in a pull request
namespace Syscall
{
@ -42,3 +43,4 @@ void sys_exec(Context* context, const char* pathname);
void sys_fcntl(Context* context, int fd, int command, uintptr_t arg);
void sys_mprotect(Context* context, void* address, size_t size, int prot);
void sys_clock(Context* context);
void sys_mkdir(Context* context, const char* filename);

View File

@ -132,12 +132,27 @@ int VFS::mkdir(const char* path, const char* name)
if (!node)
{
kwarnln("Attempting to mkdir in %s, which does not exist", path);
return -1;
return -ENOENT;
}
if (node->type != VFS_DIRECTORY)
{
kwarnln("Attempting to mkdir in %s, which is not a directory!!", path);
return -ENOTDIR;
}
if (!node->mkdir_func)
{
kwarnln("Chosen node does not support mkdir()");
return -1;
return -ENOTSUP;
}
if (!node->find_func)
{
kwarnln("Chosen node does not support finddir()");
return -ENOTSUP;
}
if (node->find_func(node, name) != nullptr)
{
kwarnln("Already exists");
return -EEXIST;
}
return node->mkdir_func(node, name);
}

View File

@ -2,6 +2,7 @@
#include "init/InitRD.h"
#include "bootboot.h"
#include "errno.h"
#include "fs/VFS.h"
#include "io/Serial.h"
#include "log/Log.h"
@ -190,23 +191,23 @@ int initrd_mkdir(VFS::Node* node, const char* name) // FIXME: Return proper erro
if (total_dirs >= 32)
{
kwarnln("mkdir() failed: too many directories");
return -1;
return -ENOSPC;
}
if (node->inode > total_dirs)
{
kwarnln("mkdir() failed: invalid node");
return -1;
return -EINVAL;
}
if (!(node->type & VFS_DIRECTORY))
{
kwarnln("mkdir() failed: not a directory");
return -1;
return -ENOTDIR;
}
InitRD::Directory& parent = dirs[node->inode];
if (parent.entries == INITRD_MAX_FILES_IN_DIR)
{
kwarnln("mkdir() failed: parent is null");
return -1;
kwarnln("mkdir() failed: parent is full");
return -ENOSPC;
}
uint64_t inode = total_dirs;
VFS::Node& new_node = nodes[total_nodes++];

View File

@ -27,6 +27,7 @@ void Syscall::entry(Context* context)
case SYS_fcntl: sys_fcntl(context, (int)context->rdi, (int)context->rsi, context->rdx); break;
case SYS_mprotect: sys_mprotect(context, (void*)context->rdi, context->rsi, (int)context->rdx); break;
case SYS_clock: sys_clock(context); break;
case SYS_mkdir: sys_mkdir(context, (const char*)context->rdi); break;
default: context->rax = -ENOSYS; break;
}
VMM::exit_syscall_context();

View File

@ -218,3 +218,19 @@ void sys_close(Context* context, int fd)
context->rax = 0;
return;
}
void sys_mkdir(Context* context, const char* filename)
{
char* kfilename = Syscall::strdup_from_user(filename);
if (!kfilename)
{
context->rax = -EFAULT;
return;
}
int rc = VFS::mkdir(kfilename);
kfree(kfilename);
context->rax = rc;
}

View File

@ -10,10 +10,14 @@ extern int errno;
#define EBADF 9 // Bad file descriptor
#define ENOMEM 12 // Cannot allocate memory
#define EFAULT 14 // Bad address
#define EEXIST 17 // File exists
#define ENOTDIR 10 // Not a directory
#define EISDIR 21 // Is a directory
#define EINVAL 22 // Invalid argument
#define EMFILE 24 // Too many open files
#define ENOSPC 28 // No space left on device
#define EPIPE 32 // Broken pipe. Not implemented.
#define ENOSYS 38 // Function not implemented
#define ENOTSUP 95 // Operation not supported.
#endif