matos/core/fsEntry.c
2024-05-23 00:21:41 +02:00

134 lines
3.0 KiB
C

#include "alloc.h"
#include "assert.h"
#include "fsEntry.h"
#include "errno.h"
#include "list.h"
#include "mem.h"
#include "stdint.h"
bool_t pstringSplipPath(struct pstr *path, struct pstr *upper, struct pstr *lower)
{
typeof(path->name) curPos = path->name;
typeof(path->len) curLen = path->len;
typeof(path->len) upperLen = 0;
// Skip leading /
while (curLen > 0 && curPos[0] == '/') {
curPos++;
curLen--;
}
upper->name = curPos;
// Find first non /
while (curLen > 0 && curPos[0] != '/') {
upperLen++;
curLen--;
curPos++;
}
upper->len = upperLen;
while (curLen > 0 && curPos[0] == '/') {
curPos++;
curLen--;
}
lower->name = curPos;
lower->len = path->len - (lower->name - path->name);
return lower->len > 0;
}
bool_t pstringIsEq(struct pstr *p1, struct pstr *p2)
{
return p1->len == p2->len && (memcmp(p1, p2, p1->len) == 0);
}
int fsEntryRef(struct fsEntry *entry)
{
entry->ref++;
return 0;
}
int fsEntryUnref(struct fsEntry **entry)
{
struct fsEntry *toDelete = NULL, *entryTmp;
entryTmp = *entry;
*entry = NULL;
while (entryTmp) {
assert(entryTmp->ref > 0);
entryTmp->ref--;
if (entryTmp->ref > 0)
break;
if (entryTmp == *entry)
entry = NULL;
if (entryTmp->parent) {
struct fsEntry *parent = entryTmp->parent;
assert(entryTmp->parent->ref >= 1);
list_delete_named(parent->childs, entryTmp, prevSiblings, nextSiblings);
// At next iteration we will decrement parent's ref cnt
}
// Avoid recursivity in kernel by using a list of entry to suppress
list_add_tail_named(toDelete, entryTmp, prevSiblings, nextSiblings);
// now, unref parent
entryTmp = entryTmp->parent;
}
// free 0 ref entries
while (!list_is_empty_named(toDelete, prevSiblings, nextSiblings)) {
entryTmp = list_pop_head_named(toDelete, prevSiblings, nextSiblings);
fsInodeUnref(entryTmp->node);
free(entryTmp);
}
return 0;
}
int fsEntryNewChild(struct fsEntry *parent, const struct pstr *name, struct inode *inode,
struct fsEntry **result)
{
struct fsEntry *entry = malloc(sizeof(struct fsEntry));
if (!entry)
return -ENOMEM;
if (name && name->len > 0) {
char *allocName = malloc(name->len);
if (!allocName) {
free(entry);
return -ENOMEM;
}
memcpy(allocName, name->name, name->len);
entry->name.len = name->len;
entry->name.name = allocName;
}
entry->ref = 1;
entry->node = inode;
entry->parent = parent;
fsInodeRef(inode);
if (parent) {
fsEntryRef(parent);
list_add_head_named(parent->childs, entry, prevSiblings, nextSiblings);
}
*result = entry;
return 0;
}
int fsEntrySetup(void){
return allocBookSlab(sizeof(struct fsEntry), PAGE_SIZE, 0, 0);
}