Files
kernel/fs/node.c
T
2020-07-28 14:54:35 +03:00

98 lines
2.4 KiB
C

#include "user/errno.h"
#include "fs/node.h"
#include "fs/vfs.h"
#include "sys/assert.h"
#include "sys/string.h"
#include "fs/fs.h"
#include "sys/debug.h"
#include "sys/panic.h"
#include "sys/heap.h"
#include "sys/mem/slab.h"
static struct slab_cache *vnode_cache = NULL;
struct vnode *vnode_create(enum vnode_type t, const char *name) {
if (!vnode_cache) {
vnode_cache = slab_cache_get(sizeof(struct vnode));
kdebug("Initialized vnode cache\n");
}
struct vnode *node = slab_calloc(vnode_cache);
_assert(node);
node->type = t;
if (name) {
_assert(strlen(name) < NODE_MAXLEN);
strcpy(node->name, name);
}
return node;
}
void vnode_destroy(struct vnode *vn) {
_assert(vnode_cache);
_assert(!vn->open_count);
slab_free(vnode_cache, vn);
}
void vnode_attach(struct vnode *parent, struct vnode *child) {
_assert(parent);
_assert(child);
_assert(!child->parent);
child->parent = parent;
child->next_child = parent->first_child;
parent->first_child = child;
}
void vnode_detach(struct vnode *node) {
_assert(node);
struct vnode *parent = node->parent;
node->parent = NULL;
if (!parent) {
return;
}
if (node == parent->first_child) {
parent->first_child = node->next_child;
node->next_child = NULL;
return;
}
for (struct vnode *ch = parent->first_child; ch; ch = ch->next_child) {
if (ch->next_child == node) {
ch->next_child = node->next_child;
node->next_child = NULL;
return;
}
}
panic("Parent has no link to its child node\n");
}
// Only dumps cached nodes in filesystem tree
void vnode_dump_tree(int level, struct vnode *node, int depth) {
// XXX: I'll reimplement this with proper symlink support
}
// NOTE: Only looks up in-memory nodes, does not perform any operations to fetch
// the nodes from storage
// NOTE: Resolution of .. and . is performed when resolving paths, as a node can
// have multiple parents (roots of filesystems mounted at different locations)
int vnode_lookup_child(struct vnode *of, const char *name, struct vnode **child) {
_assert(of);
_assert(child);
_assert(name);
_assert(strlen(name) < NODE_MAXLEN);
for (struct vnode *ch = of->first_child; ch; ch = ch->next_child) {
if (!strcmp(ch->name, name)) {
*child = ch;
return 0;
}
}
return -ENOENT;
}