Orion
Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)/* * This file handles chains of custody for files. It implements a generic set * of operations for acting on CustodyChain objects. A CustodyChain holds a * linked list of Custody objects, each of which refers to a directory entry. * With this chain, the VFS is able to find what path was used to access a * resources and go back up the chain (for implementing ..) and avoid going * beyond the root. */ #include <string.h> #include "vfs.h" #include "cache.h" #include "../mem/heap.h" /* Initialise a custody chain */ void init_custody_chain(CustodyChain *chain) { Custody *root = kmalloc(sizeof(Custody)); chain->start = chain->end = root; chain->size = 0; init_lock(&chain->lock); root->prev = root->next = NULL; root->chain = chain; root->entry = NULL; } /* Create a new custody chain */ CustodyChain * create_custody_chain(void) { CustodyChain *chain = kmalloc(sizeof(CustodyChain)); init_custody_chain(chain); return chain; } /* Clean a custody chain */ void clean_custody_chain(CustodyChain *chain) { acquire(&chain->lock); while (chain->size) remove_custody(chain); kfree(chain->start); release(&chain->lock); } /* Destroy a custody chain */ void destroy_custody_chain(CustodyChain *chain) { clean_custody_chain(chain); kfree(chain); } /* Copy custody chain */ void copy_custody_chain(CustodyChain *chain, CustodyChain *newchain) { acquire(&chain->lock); acquire(&newchain->lock); Custody *c; for (c = chain->start->next; c; c = c->next) add_custody(newchain, c->entry); release(&newchain->lock); release(&chain->lock); } /* Add entry */ void add_custody(CustodyChain *chain, DirEntry *entry) { acquire(&chain->lock); chain->end->next = kmalloc(sizeof(Custody)); chain->end->next->prev= chain->end; chain->end = chain->end->next; chain->end->chain = chain; chain->end->entry = entry_get(entry); chain->size++; release(&chain->lock); } /* Remove an entry */ DirEntry * remove_custody(CustodyChain *chain) { if (!chain->size) return NULL; acquire(&chain->lock); entry_put(chain->end->entry); chain->end = chain->end->prev; kfree(chain->end->next); chain->end->next = NULL; chain->size--; release(&chain->lock); return chain->end->entry; } /* Convert a chain to a path string */ char * custody_path(CustodyChain *chain, char *buf, size_t size) { char *ptr = buf; Custody *curr; if (!chain->start->next) { *ptr++ = '/'; *ptr = '\0'; return buf; } for (curr = chain->start->next; curr; curr = curr->next) { *ptr++ = '/'; strcpy(ptr, curr->entry->name); ptr += strlen(curr->entry->name); } *ptr = '\0'; return buf; }