#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); }