summaryrefslogtreecommitdiff
path: root/fs/vfs.c
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-10-30 22:12:14 +0100
committerAnton Kling <anton@kling.gg>2023-10-31 00:18:38 +0100
commit8a9208612eec8ddae4c418485d848ecfa0613699 (patch)
tree2f4b29200c2f0c19ae52f45bdb9b38a41b356e30 /fs/vfs.c
parentca76600acc8bf7a02346efa5bd8f17072210ec01 (diff)
Meta: Move kernel and userland to their own folders.
This is to allow both the kernel and the userland to share certain header files and to make the folder structure a bit more clear.
Diffstat (limited to 'fs/vfs.c')
-rw-r--r--fs/vfs.c318
1 files changed, 0 insertions, 318 deletions
diff --git a/fs/vfs.c b/fs/vfs.c
deleted file mode 100644
index 0c616a2..0000000
--- a/fs/vfs.c
+++ /dev/null
@@ -1,318 +0,0 @@
-#include <assert.h>
-#include <errno.h>
-#include <fs/vfs.h>
-#include <mmu.h>
-#include <poll.h>
-
-vfs_inode_t *root_dir;
-vfs_mounts_t mounts[10];
-int num_mounts = 0;
-
-vfs_fd_t *get_vfs_fd(int fd) {
- if (fd >= 100) {
- klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN);
- dump_backtrace(12);
- return NULL;
- }
- if (fd < 0) {
- klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN);
- dump_backtrace(12);
- return NULL;
- }
- return get_current_task()->file_descriptors[fd];
-}
-
-vfs_inode_t *vfs_create_inode(
- int inode_num, int type, uint8_t has_data, uint8_t can_write,
- uint8_t is_open, void *internal_object, uint64_t file_size,
- vfs_inode_t *(*open)(const char *path),
- int (*create_file)(const char *path, int mode),
- int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd),
- int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd),
- void (*close)(vfs_fd_t *fd),
- int (*create_directory)(const char *path, int mode),
- vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset,
- vfs_fd_t *fd),
- int (*truncate)(vfs_fd_t *fd, size_t length)) {
- vfs_inode_t *r = kmalloc(sizeof(inode_t));
- r->inode_num = inode_num;
- r->type = type;
- r->has_data = has_data;
- r->can_write = can_write;
- r->is_open = is_open;
- r->internal_object = internal_object;
- r->file_size = file_size;
- r->open = open;
- r->create_file = create_file;
- r->read = read;
- r->write = write;
- r->close = close;
- r->create_directory = create_directory;
- r->get_vm_object = get_vm_object;
- r->truncate = truncate;
- return r;
-}
-
-int vfs_create_fd(int flags, int mode, vfs_inode_t *inode, vfs_fd_t **fd) {
- process_t *p = (process_t *)get_current_task();
- int i;
- for (i = 0; i < 100; i++)
- if (!p->file_descriptors[i])
- break;
- if (p->file_descriptors[i])
- return -1;
- vfs_fd_t *r = kmalloc(sizeof(vfs_fd_t));
- r->flags = flags;
- r->mode = mode;
- r->inode = inode;
- r->reference_count = 1;
- p->file_descriptors[i] = r;
- if (fd)
- *fd = r;
- return i;
-}
-
-int vfs_create_file(const char *file) {
- vfs_mounts_t *file_mount = 0;
- int length = 0;
- for (int i = 0; i < num_mounts; i++) {
- int path_len = strlen(mounts[i].path);
- if (path_len <= length)
- continue;
-
- if (isequal_n(mounts[i].path, file, path_len)) {
- length = path_len;
- file_mount = &mounts[i];
- }
- }
- if (1 != length)
- file += length;
-
- if (!file_mount) {
- kprintf("vfs_internal_open could not find mounted path for file : %s\n",
- file);
- return 0;
- }
- // ext2_create_file("/etc/oscreated", 0);
- assert(file_mount->local_root->create_file);
- kprintf("Creating a file\n");
- return file_mount->local_root->create_file(file, 0);
-}
-
-vfs_inode_t *vfs_internal_open(const char *file) {
- vfs_mounts_t *file_mount = 0;
- int length = 0;
- for (int i = 0; i < num_mounts; i++) {
- int path_len = strlen(mounts[i].path);
- if (path_len <= length)
- continue;
-
- if (isequal_n(mounts[i].path, file, path_len)) {
- length = path_len;
- file_mount = &mounts[i];
- }
- }
- if (1 != length)
- file += length;
-
- if (!file_mount) {
- kprintf("vfs_internal_open could not find mounted path for file : %s\n",
- file);
- return NULL;
- }
-
- vfs_inode_t *ret = file_mount->local_root->open(file);
- return ret;
-}
-
-char *vfs_clean_path(const char *path, char *resolved_path) {
- // char *const clean = kmalloc(strlen(path) + 1);
- char *clean = resolved_path;
- int prev_slash = 0;
- char *ptr = clean;
- for (; *path; path++) {
- if (prev_slash && '/' == *path) {
- continue;
- }
- prev_slash = ('/' == *path);
- *ptr = *path;
- ptr++;
- }
- *ptr = '\0';
- return clean;
-}
-
-char *vfs_resolve_path(const char *file, char *resolved_path) {
- if ('/' == *file) {
- return vfs_clean_path(file, resolved_path);
- }
- const char *cwd = get_current_task()->current_working_directory;
- size_t l = strlen(cwd);
- assert(l > 0);
- assert('/' == cwd[l - 1]);
- // char *r = kmalloc(l + strlen(file) + 1);
- char r[256];
- strcpy(r, cwd);
- strcat(r, file);
- char *final = vfs_clean_path(r, resolved_path);
- // kfree(r);
- return final;
-}
-
-int vfs_mkdir(const char *path, int mode) {
- vfs_mounts_t *file_mount = 0;
- int length = 0;
- for (int i = 0; i < num_mounts; i++) {
- int path_len = strlen(mounts[i].path);
- if (path_len <= length)
- continue;
-
- if (isequal_n(mounts[i].path, path, path_len)) {
- length = path_len;
- file_mount = &mounts[i];
- }
- }
- if (1 != length)
- path += length;
-
- if (!file_mount) {
- kprintf("vfs_internal_open could not find mounted path for file : %s\n",
- path);
- return 0;
- }
- assert(file_mount->local_root->create_directory);
- // TODO: Error checking, don't just assume it is fine
- file_mount->local_root->create_directory(path, mode);
- return 0;
-}
-
-int vfs_open(const char *file, int flags, int mode) {
- char resolved_path[256] = {0};
- vfs_resolve_path(file, resolved_path);
- vfs_inode_t *inode = vfs_internal_open(resolved_path);
- if (0 == inode) {
- if (mode & O_CREAT) {
- if (vfs_create_file(resolved_path)) {
- klog("VFS: File created", LOG_NOTE);
- return vfs_open(file, flags, mode);
- }
- klog("VFS: Could not create file", LOG_WARN);
- }
- return -ENOENT;
- }
- if (inode->type == FS_TYPE_UNIX_SOCKET) {
- return uds_open(resolved_path);
- }
-
- return vfs_create_fd(flags, mode, inode, NULL);
-}
-
-int vfs_close(int fd) {
- vfs_fd_t *fd_ptr = get_vfs_fd(fd);
- if (NULL == fd_ptr) {
- return -1;
- }
- assert(0 < fd_ptr->reference_count);
- // Remove process reference
- fd_ptr->reference_count--;
- get_current_task()->file_descriptors[fd] = 0;
- // If no references left then free the contents
- if (0 == fd_ptr->reference_count) {
- if (fd_ptr->inode->close)
- fd_ptr->inode->close(fd_ptr);
-
- kfree(fd_ptr);
- }
- return 0;
-}
-
-int raw_vfs_pread(vfs_fd_t *vfs_fd, void *buf, uint64_t count,
- uint64_t offset) {
- if (!(vfs_fd->flags & O_READ))
- return -EBADF;
- return vfs_fd->inode->read(buf, offset, count, vfs_fd);
-}
-
-int vfs_pread(int fd, void *buf, uint64_t count, uint64_t offset) {
- if (fd >= 100) {
- kprintf("EBADF : %x\n", fd);
- return -EBADF;
- }
- if (fd < 0) {
- dump_backtrace(12);
- kprintf("EBADF : %x\n", fd);
- return -EBADF;
- }
- vfs_fd_t *vfs_fd = get_current_task()->file_descriptors[fd];
- if (!vfs_fd)
- return -EBADF;
- int rc = raw_vfs_pread(vfs_fd, buf, count, offset);
- if (-EAGAIN == rc && count > 0) {
- if (!(vfs_fd->flags & O_NONBLOCK)) {
- struct pollfd fds;
- fds.fd = fd;
- fds.events = POLLIN;
- fds.revents = 0;
- poll(&fds, 1, 0);
- return vfs_pread(fd, buf, count, offset);
- }
- }
- return rc;
-}
-
-int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, uint64_t count,
- uint64_t offset) {
- assert(vfs_fd);
- assert(vfs_fd->inode);
- assert(vfs_fd->inode->write);
- return vfs_fd->inode->write(buf, offset, count, vfs_fd);
-}
-
-int vfs_pwrite(int fd, void *buf, uint64_t count, uint64_t offset) {
- vfs_fd_t *vfs_fd = get_vfs_fd(fd);
- if (!vfs_fd)
- return -EBADF;
- if (!(vfs_fd->flags & O_WRITE)) {
- return -EBADF;
- }
- return raw_vfs_pwrite(vfs_fd, buf, count, offset);
-}
-
-vfs_vm_object_t *vfs_get_vm_object(int fd, uint64_t length, uint64_t offset) {
- vfs_fd_t *vfs_fd = get_vfs_fd(fd);
- if (!vfs_fd)
- return NULL;
- vfs_vm_object_t *r = vfs_fd->inode->get_vm_object(length, offset, vfs_fd);
- return r;
-}
-
-int vfs_dup2(int org_fd, int new_fd) {
- get_current_task()->file_descriptors[new_fd] =
- get_current_task()->file_descriptors[org_fd];
- get_current_task()->file_descriptors[new_fd]->reference_count++;
- return 1;
-}
-
-int vfs_ftruncate(int fd, size_t length) {
- vfs_fd_t *fd_ptr = get_vfs_fd(fd);
- if (!fd_ptr)
- return -EBADF;
- if (!(fd_ptr->flags & O_READ))
- return -EINVAL;
- vfs_inode_t *inode = fd_ptr->inode;
- if (!inode)
- return -EINVAL;
- if (!inode->truncate)
- return -EINVAL;
-
- return inode->truncate(fd_ptr, length);
-}
-
-void vfs_mount(char *path, vfs_inode_t *local_root) {
- int len = strlen(path);
- mounts[num_mounts].path = kmalloc_eternal(len + 1);
- memcpy(mounts[num_mounts].path, path, len);
- mounts[num_mounts].path[len] = '\0';
- mounts[num_mounts].local_root = local_root;
- num_mounts++;
-}