2026-07-07 00:13:24 -05:00
|
|
|
#include <vfs.h>
|
|
|
|
|
#include <process.h>
|
|
|
|
|
#include <scheduler.h>
|
2026-06-30 00:03:21 -05:00
|
|
|
|
2026-07-07 00:13:24 -05:00
|
|
|
#include <lib/memory.h>
|
2026-07-10 07:46:46 -05:00
|
|
|
#include <lib/string.h>
|
|
|
|
|
#include <lib/print.h>
|
2026-06-29 17:00:07 -05:00
|
|
|
|
|
|
|
|
vfs_node_t* root = NULL;
|
|
|
|
|
|
2026-06-30 00:03:21 -05:00
|
|
|
vfs_node_t* vfs_create_root() {
|
2026-06-29 17:00:07 -05:00
|
|
|
root = kalloc(sizeof(vfs_node_t));
|
2026-06-30 00:03:21 -05:00
|
|
|
memset((uint8_t*)root, 0, sizeof(vfs_node_t));
|
|
|
|
|
|
|
|
|
|
strcpy(root->name, "root");
|
|
|
|
|
|
2026-06-29 17:00:07 -05:00
|
|
|
root->flags |= VFS_DIRECTORY;
|
2026-06-30 00:03:21 -05:00
|
|
|
root->size = 0;
|
2026-07-11 10:33:08 -05:00
|
|
|
root->find = NULL;
|
2026-06-30 00:03:21 -05:00
|
|
|
|
|
|
|
|
return root;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-10 07:46:46 -05:00
|
|
|
void vfs_mount(vfs_node_t* _mnt, vfs_node_t* _fs) {
|
2026-06-30 00:03:21 -05:00
|
|
|
if (!_fs || !_mnt || !(_mnt->flags & VFS_DIRECTORY)) return;
|
2026-06-30 19:26:31 -05:00
|
|
|
_mnt->mnt = _fs;
|
2026-06-30 00:03:21 -05:00
|
|
|
}
|
|
|
|
|
|
2026-07-10 07:46:46 -05:00
|
|
|
vfs_node_t* vfs_find(const char* path) {
|
2026-06-30 00:03:21 -05:00
|
|
|
vfs_node_t* current = root;
|
2026-07-12 03:56:25 -05:00
|
|
|
if (current->mnt) {
|
|
|
|
|
current = current->mnt;
|
|
|
|
|
}
|
2026-06-30 00:03:21 -05:00
|
|
|
|
2026-07-11 10:33:08 -05:00
|
|
|
char* sav = NULL;
|
2026-07-10 07:46:46 -05:00
|
|
|
size_t path_sz = strlen(path) + 1;
|
|
|
|
|
char* path_cpy = kalloc(path_sz);
|
|
|
|
|
memset((uint8_t*)path_cpy, 0, path_sz);
|
|
|
|
|
memcpy(path, path_cpy, path_sz);
|
|
|
|
|
|
|
|
|
|
char* tkn = strtok_r(path_cpy, "/", &sav);
|
|
|
|
|
while (tkn != NULL) {
|
2026-07-12 03:56:25 -05:00
|
|
|
if (current && current->mnt) {
|
|
|
|
|
current = current->mnt;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-11 10:33:08 -05:00
|
|
|
if (!current || !current->find) {
|
2026-07-11 10:36:30 -05:00
|
|
|
return NULL;
|
2026-07-11 10:33:08 -05:00
|
|
|
}
|
2026-07-12 03:56:25 -05:00
|
|
|
|
2026-07-11 10:33:08 -05:00
|
|
|
current = current->find(current, tkn);
|
2026-06-30 00:03:21 -05:00
|
|
|
|
2026-07-11 10:33:08 -05:00
|
|
|
if (current == NULL) {
|
2026-07-11 10:36:30 -05:00
|
|
|
return NULL;
|
2026-07-11 10:33:08 -05:00
|
|
|
}
|
2026-06-30 00:03:21 -05:00
|
|
|
|
2026-07-12 03:56:25 -05:00
|
|
|
tkn = strtok_r(NULL, "/", &sav);
|
2026-07-11 10:36:30 -05:00
|
|
|
if (tkn && !(current->flags & VFS_DIRECTORY)) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2026-06-30 00:03:21 -05:00
|
|
|
}
|
|
|
|
|
|
2026-07-12 03:56:25 -05:00
|
|
|
kfree(path_cpy);
|
2026-07-11 10:36:30 -05:00
|
|
|
return current;
|
2026-06-30 00:03:21 -05:00
|
|
|
}
|
|
|
|
|
|
2026-07-10 07:46:46 -05:00
|
|
|
vfs_node_t* vfs_mkdir(vfs_node_t* parent, const char* name) {
|
2026-07-11 10:33:08 -05:00
|
|
|
if (!parent || !name) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strlen(name) == 0) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return parent->mkdir(parent, name);
|
2026-07-10 07:46:46 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int vfs_open(const char* _path, int flags) {
|
|
|
|
|
vfs_node_t* file = vfs_find(_path);
|
2026-06-30 00:03:21 -05:00
|
|
|
if (!file) return -1;
|
2026-07-07 00:13:24 -05:00
|
|
|
|
|
|
|
|
file_t* f = (file_t*)kalloc(sizeof(file_t));
|
|
|
|
|
f->node = file;
|
|
|
|
|
f->offset = 0;
|
|
|
|
|
f->flags = flags;
|
|
|
|
|
|
|
|
|
|
return alloc_fd(f);
|
2026-06-30 00:03:21 -05:00
|
|
|
}
|
|
|
|
|
|
2026-07-10 07:46:46 -05:00
|
|
|
int vfs_read(int fd, void* buf, size_t sz) {
|
2026-07-07 00:13:24 -05:00
|
|
|
process_t* curr_p = current_task();
|
|
|
|
|
if (fd < 0 || fd >= MAX_PROCESS_FDS || !curr_p->fd_table[fd]->node) {
|
2026-06-30 00:03:21 -05:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-07 00:13:24 -05:00
|
|
|
file_t* file = curr_p->fd_table[fd];
|
2026-06-30 00:03:21 -05:00
|
|
|
|
|
|
|
|
if (!file->node->read) return -1;
|
|
|
|
|
|
|
|
|
|
uint32_t bytes_read = file->node->read(file->node, file->offset, sz, buf);
|
|
|
|
|
file->offset += bytes_read;
|
|
|
|
|
|
|
|
|
|
return bytes_read;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-10 07:46:46 -05:00
|
|
|
int vfs_seek(int fd, size_t offset) {
|
2026-07-07 00:13:24 -05:00
|
|
|
process_t* curr_p = current_task();
|
|
|
|
|
if (fd < 0 || fd >= MAX_PROCESS_FDS || !curr_p->fd_table[fd]->node) {
|
2026-06-30 19:26:31 -05:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-07 00:13:24 -05:00
|
|
|
file_t* file = curr_p->fd_table[fd];
|
2026-06-30 19:26:31 -05:00
|
|
|
file->offset = offset;
|
|
|
|
|
return 1;
|
2026-07-10 07:46:46 -05:00
|
|
|
}
|
2026-07-07 00:13:24 -05:00
|
|
|
|
|
|
|
|
int alloc_fd(file_t* f) {
|
|
|
|
|
process_t* curr_p = current_task();
|
|
|
|
|
if (!curr_p) return -1;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < MAX_PROCESS_FDS; i++) {
|
|
|
|
|
if (curr_p->fd_table[i] == NULL) {
|
|
|
|
|
curr_p->fd_table[i] = f;
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|