Files
RockOS/kernel/vfs.c

107 lines
2.3 KiB
C

#include <vfs.h>
#include <process.h>
#include <scheduler.h>
#include <lib/memory.h>
vfs_node_t* root = NULL;
vfs_node_t* vfs_create_root() {
root = kalloc(sizeof(vfs_node_t));
memset((uint8_t*)root, 0, sizeof(vfs_node_t));
strcpy(root->name, "root");
root->flags |= VFS_DIRECTORY;
root->size = 0;
root->finddir = NULL;
return root;
}
void mount(vfs_node_t* _mnt, vfs_node_t* _fs) {
if (!_fs || !_mnt || !(_mnt->flags & VFS_DIRECTORY)) return;
_mnt->mnt = _fs;
}
static vfs_node_t* lookup(const char* path) {
if (path[0] != '/') return NULL;
vfs_node_t* current = root;
if (current->mnt) {
current = current->mnt;
}
const char* cmp = path + 1;
if (*cmp == '\0') return current;
if (current->finddir) {
return current->finddir(current, cmp);
}
return NULL;
}
int open(const char* _path, int flags) {
vfs_node_t* file = lookup(_path);
if (!file) return -1;
file_t* f = (file_t*)kalloc(sizeof(file_t));
f->node = file;
f->offset = 0;
f->flags = flags;
return alloc_fd(f);
}
int read(int fd, void* buf, size_t sz) {
process_t* curr_p = current_task();
if (fd < 0 || fd >= MAX_PROCESS_FDS || !curr_p->fd_table[fd]->node) {
return -1;
}
file_t* file = curr_p->fd_table[fd];
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;
}
int fstat(int fd, file_t* dst) {
process_t* curr_p = current_task();
if (fd < 0 || fd >= MAX_PROCESS_FDS || !curr_p->fd_table[fd]->node) {
return 0;
}
file_t* src = curr_p->fd_table[fd];
memcpy(src, dst, sizeof(file_t));
return 1;
}
int fseek(int fd, size_t offset) {
process_t* curr_p = current_task();
if (fd < 0 || fd >= MAX_PROCESS_FDS || !curr_p->fd_table[fd]->node) {
return 0;
}
file_t* file = curr_p->fd_table[fd];
file->offset = offset;
return 1;
}
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;
}