Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion kernel/include/fs/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ typedef struct
}
vfs_dirent_t;

int vfs_destroy(vnode_t *vn);

/**
* @brief Increment vnode reference count.
*
Expand All @@ -98,14 +100,17 @@ static inline bool vnode_unref(vnode_t *vn)
{
if (atomic_fetch_sub_explicit(&vn->refcount, 1, memory_order_acq_rel) == 1)
{
// TODO: run vnode destructor
vfs_destroy(vn);
return true;
}
return false;
}

struct vnode_ops
{
int (*open) (vnode_t *vn, int flags, void *cred);
int (*close) (vnode_t *vp, int flags, void *cred);
int (*destroy)(vnode_t *vn, int flags);
int (*read) (vnode_t *vn, void *buffer, uint64_t offset, uint64_t count, uint64_t *out_bytes_read);
int (*write) (vnode_t *vn, const void *buffer, uint64_t offset, uint64_t count, uint64_t *out_bytes_written);
int (*lookup) (vnode_t *vn, const char *name, vnode_t **out_vn);
Expand All @@ -123,6 +128,8 @@ struct vnode_ops

[[nodiscard]] int vfs_read(vnode_t *vn, void *buffer, uint64_t offset, uint64_t count, uint64_t *out_bytes_read);
[[nodiscard]] int vfs_write(vnode_t *vn, void *buffer, uint64_t offset, uint64_t count, uint64_t *out_bytes_written);
[[nodiscard]] int vfs_open(vnode_t *vn, int flags, void *cred);
[[nodiscard]] int vfs_close(vnode_t *vn, int flags, void *cred);
[[nodiscard]] int vfs_lookup(const char *path, vnode_t **out_vn);
[[nodiscard]] int vfs_create(const char *path, vnode_type_t type, vnode_t **out_vn);
[[nodiscard]] int vfs_remove(const char *path);
Expand Down
1 change: 0 additions & 1 deletion kernel/include/mm/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ typedef struct
{
uintptr_t start;
size_t length;
int prot;

int prot;
int flags;
Expand Down
34 changes: 34 additions & 0 deletions kernel/source/fs/ramfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,18 @@ vfs_ops_t ramfs_ops = {

static int read (vnode_t *self, void *buf, uint64_t offset, uint64_t count, uint64_t *out);
static int write (vnode_t *self, const void *buf, uint64_t offset, uint64_t count, uint64_t *out);
static int open (vnode_t *self, int flags, void *cred);
static int close (vnode_t *self, int flags, void *cred);
static int destroy(vnode_t *self, int flags);
static int lookup(vnode_t *self, const char *name, vnode_t **out);
static int create(vnode_t *self, const char *name, vnode_type_t t, vnode_t **out);
static int remove(vnode_t *self, const char *name);
static int readdir(vnode_t *self, vfs_dirent_t **out_entries, size_t *out_count);

vnode_ops_t ramfs_node_ops = {
.open = open,
.close = close,
.destroy = destroy,
.read = read,
.write = write,
.lookup = lookup,
Expand All @@ -60,6 +66,30 @@ static vnode_t *ramfs_get_root(vfs_t *self)
return (vnode_t *)self->private_data;
}

static int open(vnode_t *self, int flags, void *cred)
{
if (!self)
return EINVAL;

ramfs_node_t *node = (ramfs_node_t *)self;

// TODO: implement proper credential checking)
// TODO: Can't open directory for writing

node->vn.atime = arch_clock_get_unix_time();

return EOK;
}

static int close(vnode_t *self, int flags, void *cred)
{
if (!self)
return EINVAL;

return EOK;
}


// Node Operations

static int read(vnode_t *self, void *buf, uint64_t offset, uint64_t count, uint64_t *out)
Expand Down Expand Up @@ -115,6 +145,7 @@ static int write(vnode_t *self, const void *buf, uint64_t offset, uint64_t count
{
page = (void*)(pm_alloc(0)->addr + HHDM);
xa_insert(&node->pages, page_idx, page);
node->page_count = page_idx + 1;
}

memcpy((uint8_t *)page + page_off, src + written, to_copy);
Expand Down Expand Up @@ -200,6 +231,9 @@ static int remove(vnode_t *self, const char *name)
ramfs_node_t *child = LIST_GET_CONTAINER(n, ramfs_node_t, list_node);
if (strcmp(child->vn.name, name) == 0)
{
if (atomic_load(&child->vn.refcount) > 1)
return EBUSY;

list_remove(&current->children, &child->list_node);
FOREACH(c, child->children)
{
Expand Down
42 changes: 40 additions & 2 deletions kernel/source/fs/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ int vfs_lookup(const char *path, vnode_t **out_vn)
{
vnode_t *curr;
path = vfs_get_mountpoint(path, &curr);

const char *comp;
size_t comp_len;

Expand All @@ -111,9 +112,11 @@ int vfs_lookup(const char *path, vnode_t **out_vn)
memcpy(name_buf, comp, comp_len);
name_buf[comp_len] = '\0';

if (curr->ops->lookup(curr, name_buf, &curr) != EOK)
vnode_t *next;
if (curr->ops->lookup(curr, name_buf, &next) != EOK)
return ENOENT;


curr = next;
path = comp + comp_len;
}

Expand Down Expand Up @@ -172,6 +175,41 @@ int vfs_ioctl(vnode_t *vn, uint64_t cmd, void *arg)
return vn->ops->ioctl(vn, cmd, arg);
}

int vfs_open(vnode_t *vn, int flags, void *cred)
{
if (!vn)
return EINVAL;

// TODO: permission checks

if (vn->ops->open)
return vn->ops->open(vn, flags, cred);

return ENOTSUP;
}

int vfs_close(vnode_t *vn, int flags, void *cred)
{
if (!vn)
return EINVAL;

// TODO: permission checks

if (vn->ops->close)
return vn->ops->close(vn, flags, cred);

return ENOTSUP;
}
int vfs_destroy(vnode_t *vn)
{
if (!vn)
return EINVAL;

if (vn->ops && vn->ops->destroy)
return vn->ops->destroy(vn, 0);

return ENOTSUP;
}
void vfs_init()
{
vfs_t *ramfs = ramfs_create();
Expand Down