diff options
Diffstat (limited to 'src/libs/uio/mounttree.c')
-rw-r--r-- | src/libs/uio/mounttree.c | 814 |
1 files changed, 814 insertions, 0 deletions
diff --git a/src/libs/uio/mounttree.c b/src/libs/uio/mounttree.c new file mode 100644 index 0000000..eb5bdec --- /dev/null +++ b/src/libs/uio/mounttree.c @@ -0,0 +1,814 @@ +/* + * Copyright (C) 2003 Serge van den Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * Nota bene: later versions of the GNU General Public License do not apply + * to this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <stdlib.h> +#include <string.h> +#ifdef DEBUG +# include <stdio.h> +#endif +#include <assert.h> + +#include "iointrn.h" +#include "uioport.h" +#include "mounttree.h" +#include "paths.h" +#include "types.h" +#include "mem.h" +#include "uioutils.h" +#ifdef uio_MEM_DEBUG +# include "memdebug.h" +#endif + +static uio_MountTree *uio_mountTreeAddMountInfoRecTree( + uio_Repository *repository, uio_MountTree *tree, + uio_MountInfo *mountInfo, const char *start, const char *end, + uio_PathComp *upComp, uio_MountLocation location, + const uio_MountInfo *relative); +static inline uio_MountTree *uio_mountTreeAddMountInfoRecTreeSub( + uio_Repository *repository, uio_MountTree **tree, + uio_MountInfo *mountInfo, const char *start, + const char *end, uio_MountLocation location, + const uio_MountInfo *relative); +static void uio_mountTreeAddMountInfoLocAll(uio_Repository *repository, + uio_MountTree *tree, uio_MountInfo *mountInfo, int depth, + uio_MountLocation location, const uio_MountInfo *relative); +static uio_MountTreeItem *uio_copyMountTreeItems(uio_MountTreeItem *item, + int extraDepth); +static void uio_addMountTreeItem(uio_Repository *repository, + uio_MountTreeItem **pLocs, uio_MountTreeItem *item, + uio_MountLocation location, const uio_MountInfo *relative); +static uio_MountTree *uio_mountTreeAddNewSubTree(uio_Repository *repository, + uio_MountTree *tree, const char *path, uio_MountInfo *mountInfo, + uio_PathComp *upComp, uio_MountLocation location, + const uio_MountInfo *relative); +static void uio_mountTreeAddSub(uio_MountTree *tree, uio_MountTree *sub); +static uio_MountTree * uio_splitMountTree(uio_MountTree **tree, uio_PathComp + *lastComp, int depth); +static void uio_mountTreeRemoveMountInfoRec(uio_MountTree *mountTree, + uio_MountInfo *mountInfo); +static void uio_printMount(FILE *outStream, const uio_MountInfo *mountInfo); + +static inline uio_MountTree * uio_MountTree_new(uio_MountTree *subTrees, + uio_MountTreeItem *pLocs, uio_MountTree *upTree, uio_PathComp + *comps, uio_PathComp *lastComp, uio_MountTree *next); +static inline uio_MountTreeItem *uio_MountTree_newItem( + uio_MountInfo *mountInfo, int depth, uio_MountTreeItem *next); + +static inline void uio_MountTreeItem_delete(uio_MountTreeItem *item); + +static inline uio_MountTree *uio_MountTree_alloc(void); +static inline uio_MountTreeItem *uio_MountTreeItem_alloc(void); +static inline uio_MountInfo *uio_MountInfo_alloc(void); + +static inline void uio_MountTree_free(uio_MountTree *mountTree); +static inline void uio_MountTreeItem_free(uio_MountTreeItem *mountTreeItem); +static inline void uio_MountInfo_free(uio_MountInfo *mountInfo); + + +// make the root mount Tree +uio_MountTree * +uio_makeRootMountTree(void) { + return uio_MountTree_new(NULL, NULL, NULL, NULL, NULL, NULL); +} + +// Add a MountInfo structure to a MountTree in the place pointed +// to by 'path'. +// returns the MountTree for the location at the end of the path +uio_MountTree * +uio_mountTreeAddMountInfo(uio_Repository *repository, uio_MountTree *mountTree, + uio_MountInfo *mountInfo, const char *path, uio_MountLocation location, + const uio_MountInfo *relative) { + const char *start, *end; + + getFirstPath0Component(path, &start, &end); + return uio_mountTreeAddMountInfoRecTree(repository, mountTree, mountInfo, + start, end, NULL, location, relative); +} + +// recursive helper for uio_mountTreeAddMountInfo +// returns the MountTree for the location at the end of the path +static uio_MountTree * +uio_mountTreeAddMountInfoRecTree(uio_Repository *repository, uio_MountTree *tree, + uio_MountInfo *mountInfo, const char *start, const char *end, + uio_PathComp *upComp, + uio_MountLocation location, const uio_MountInfo *relative) { + uio_MountTree **sub; + + if (*start == '\0') { + // End of the path. Put the MountInfo here and on all subtrees below + // this level. + uio_mountTreeAddMountInfoLocAll(repository, tree, mountInfo, 0, + location, relative); + return tree; + } + + // Check if sub trees match the path. + for (sub = &tree->subTrees; *sub != NULL; sub = &(*sub)->next) { + uio_MountTree *resTree; + + resTree = uio_mountTreeAddMountInfoRecTreeSub(repository, sub, + mountInfo, start, end, location, relative); + if (resTree != NULL) { + // handled + return resTree; + } + } + // No subtree found matching (part of) 'path'. + + // Need to add a new tree sub + return uio_mountTreeAddNewSubTree(repository, tree, start, mountInfo, + upComp, location, relative); +} + +// recursive helper for uio_mountTreeAddMountInfo +// Pre: *start != '\0' +// returns the MountTree for the location at the end of the path, if +// that falls within this tree. If not, returns NULL. +static inline uio_MountTree * +uio_mountTreeAddMountInfoRecTreeSub(uio_Repository *repository, + uio_MountTree **tree, uio_MountInfo *mountInfo, + const char *start, const char *end, uio_MountLocation location, + const uio_MountInfo *relative) { + uio_PathComp *comp, *lastComp; + int depth; + + comp = (*tree)->comps; + if (strncmp(comp->name, start, end - start) != 0 || + comp->name[end - start] != '\0') { + // first component does not match; this is not the correct subTree + return NULL; + } + + depth = 1; + // try to match all components of the directory path to this subTree. + while (1) { + getNextPath0Component(&start, &end); + lastComp = comp; + comp = comp->next; + + if (comp == NULL) + break; + + if (*start == '\0') { + // end of the path reached + // We need to split up the components and insert a new + // MountTree here. + uio_MountTree *newTree; + newTree = uio_splitMountTree(tree, lastComp, depth); + + // Add mountInfo to each of the MountTrees below newTree. + uio_mountTreeAddMountInfoLocAll(repository, newTree, mountInfo, 0, + location, relative); + + return newTree; + } + if (strncmp(comp->name, start, end - start) != 0 || + comp->name[end - start] != '\0') { + // Some, but not all components matched; we need to split + // up the components and add a new subTree here for the + // (non-matching) rest of the path. + uio_MountTree *newTree; + + newTree = uio_splitMountTree(tree, lastComp, depth); + + // A new Tree is added at the split-point. + return uio_mountTreeAddNewSubTree(repository, newTree, start, + mountInfo, lastComp, location, relative); + } + getNextPath0Component(&start, &end); + depth++; + } + + // All components matched. We can recurse to the next subdir. + return uio_mountTreeAddMountInfoRecTree(repository, *tree, mountInfo, + start, end, lastComp, location, relative); +} + +// Add a MountInfo struct 'mountInfo' to the pLocs fields of all subTrees +// starting with 'tree'. +// 'depth' is the distance to the MountTree where the MountInfo is located. +static void +uio_mountTreeAddMountInfoLocAll(uio_Repository *repository, uio_MountTree *tree, + uio_MountInfo *mountInfo, int depth, uio_MountLocation location, + const uio_MountInfo *relative) { + uio_MountTreeItem *newPLoc; + uio_MountTree *subTree; + int compCount; + + // Add a new PLoc to this mountTree + newPLoc = uio_MountTree_newItem(mountInfo, depth, NULL); + uio_addMountTreeItem(repository, &tree->pLocs, newPLoc, location, relative); + + // Recurse for subtrees + for (subTree = tree->subTrees; subTree != NULL; + subTree = subTree->next) { + compCount = uio_countPathComps(subTree->comps); + uio_mountTreeAddMountInfoLocAll( + repository, subTree, mountInfo, depth + compCount, + location, relative); + } +} + +// pre: repository->mounts is already updated +// pre: if location is uio_MOUNT_BELOW or uio_MOUNT_ABOVE, 'relative' +// exists in repository->mounts +static void +uio_addMountTreeItem(uio_Repository *repository, uio_MountTreeItem **pLocs, + uio_MountTreeItem *item, + uio_MountLocation location, const uio_MountInfo *relative) { + switch (location) { + case uio_MOUNT_TOP: + item->next = *pLocs; + *pLocs = item; + break; + case uio_MOUNT_BOTTOM: + while (*pLocs != NULL) + pLocs = &(*pLocs)->next; + item->next = NULL; + *pLocs = item; + break; + case uio_MOUNT_ABOVE: { + uio_MountInfo **mountInfo; + mountInfo = repository->mounts; + while (*mountInfo != relative) { + assert(*mountInfo != NULL); + if ((*pLocs)->mountInfo == *mountInfo) + pLocs = &(*pLocs)->next; + mountInfo++; + } + item->next = *pLocs; + *pLocs = item; + break; + } + case uio_MOUNT_BELOW: { + uio_MountInfo **mountInfo; + mountInfo = repository->mounts; + while (*mountInfo != relative) { + assert(*mountInfo != NULL); + if ((*pLocs)->mountInfo == *mountInfo) + pLocs = &(*pLocs)->next; + mountInfo++; + } + item->next = (*pLocs)->next; + (*pLocs)->next = item; + break; + } + default: + assert(false); + } +} + +// Copy a chain of MountTreeItems, but increase the depth by 'extraDepth'. +static uio_MountTreeItem * +uio_copyMountTreeItems(uio_MountTreeItem *item, int extraDepth) { + uio_MountTreeItem *result, **resPtr; + uio_MountTreeItem *newItem; + + resPtr = &result; + while (item != NULL) { + newItem = uio_MountTree_newItem( + item->mountInfo, item->depth + extraDepth, NULL); + *resPtr = newItem; + resPtr = &newItem->next; + item = item->next; + } + *resPtr = NULL; + return result; +} + +// add a new sub tree under a tree 'tree'. +// 'path' is the part leading up to the new tree and +// 'mountInfo' is the MountInfo structure to at there. +// 'upComp' points to the last path component that lead to 'tree'. +static uio_MountTree * +uio_mountTreeAddNewSubTree(uio_Repository *repository, uio_MountTree *tree, + const char *path, uio_MountInfo *mountInfo, uio_PathComp *upComp, + uio_MountLocation location, const uio_MountInfo *relative) { + uio_MountTreeItem *item, *items; + uio_MountTree *newTree; + uio_PathComp *compList, *lastComp; + int compCount; + + compList = uio_makePathComps(path, upComp); + compCount = uio_countPathComps(compList); + lastComp = uio_lastPathComp(compList); + item = uio_MountTree_newItem(mountInfo, 0, NULL); + item->next = NULL; + items = uio_copyMountTreeItems(tree->pLocs, compCount); + uio_addMountTreeItem(repository, &items, item, location, + relative); + newTree = uio_MountTree_new( + NULL /* subTrees */, + items /* pLocs */, + tree /* upTree */, + compList /* comps */, + lastComp /* lastComp */, + NULL /* next */); + uio_mountTreeAddSub(tree, newTree); + return newTree; +} + +// add a sub structure to the end of the 'subTrees' list of a tree. +static void +uio_mountTreeAddSub(uio_MountTree *tree, uio_MountTree *sub) { + uio_MountTree **subPtr; + + for (subPtr = &tree->subTrees; *subPtr != NULL; + subPtr = &(*subPtr)->next) { + // Nothing to do here. + } + *subPtr = sub; +} + +// Add a new MountTree structure in between two MountTrees. +// Tree points to the pointer for the tree in front of which the new +// tree needs to be placed (at depth 'depth'). +// 'lastComp' is the last pathComp of the part before the splitting point +// It returns the new MountTree. +static uio_MountTree * +uio_splitMountTree(uio_MountTree **tree, uio_PathComp *lastComp, int depth) { + uio_MountTree *newTree; + uio_MountTreeItem *items; + + items = uio_copyMountTreeItems((*tree)->upTree->pLocs, depth); + newTree = uio_MountTree_new( + *tree /* subTrees */, + items /* pLocs */, + (*tree)->upTree /* upTree */, + (*tree)->comps /* comps */, + lastComp /* lastComp */, + NULL /* next */); + (*tree)->upTree = newTree; + (*tree)->comps = lastComp->next; + lastComp->next = NULL; + *tree = newTree; + return newTree; +} + +void +uio_mountTreeRemoveMountInfo(uio_Repository *repository, + uio_MountTree *mountTree, uio_MountInfo *mountInfo) { + uio_MountTree **subTreePtr; + uio_MountTree *upTree; + + // If the tree has no sub-trees and it has the same items as the + // upTree, with 'mountInfo' added, then the tree is a dead end + // and can be removed entirely. + // First we handle the other case. + // Note that if the upTree has exactly one item less than the tree + // itself, these items must be the same, plus mountInfo for the + // tree itself, as each tree has at least the items of its upTree. + if (mountTree->upTree == NULL || mountTree->subTrees != NULL || + uio_mountTreeCountPLocs(mountTree) != + uio_mountTreeCountPLocs(mountTree->upTree) + 1) { + // We can't remove the tree itself. + // We need to remove the mountInfo from the tree, and all subTrees. + // Then we're done. + uio_mountTreeRemoveMountInfoRec(mountTree, mountInfo); + return; + } + + // mountTree itself can be removed. + // First remove the tree from the list of subtrees of the upTree. + subTreePtr = &mountTree->upTree->subTrees; + while (1) { + assert(*subTreePtr != NULL); + if (*subTreePtr == mountTree) + break; + subTreePtr = &(*subTreePtr)->next; + } + *subTreePtr = mountTree->next; + + // Save the upTree for later. + upTree = mountTree->upTree; + + // Remove the tree itself. + uio_MountTree_delete(mountTree); + + // The upTree itself could have become unnecessary now. + // This is the case when upTree now only has one subTree, and upTree + // and the subTree have the same items. + // Again, same item count implies same items. + if (upTree->subTrees == NULL || upTree->subTrees->next != NULL || + uio_mountTreeCountPLocs(upTree) != + uio_mountTreeCountPLocs(upTree->subTrees)) { + // upTree is still necessary. We're done. + return; + } + + // Merge upTree and upTree->subTrees. + // It would be easiest to keep upTree, and throw upTree->subTrees away, + // but that's not possible as external links point to upTree->subTrees. + // First merge the path components: + assert(upTree->subTrees->lastComp != NULL); + upTree->subTrees->lastComp->next = upTree->subTrees->comps; + upTree->subTrees->lastComp = upTree->lastComp; + upTree->subTrees->comps = upTree->comps; + // Now let the pointer that pointed to upTree, point to upTree->subTrees. + // Change upTree->next accordingly. + if (upTree->upTree == NULL) { + assert(repository->mountTree == upTree); + repository->mountTree = upTree->subTrees; + // upTree->subTrees->next is already NULL + } else { + uio_MountTree *next; + subTreePtr = &upTree->upTree->subTrees; + while (1) { + assert(*subTreePtr != NULL); + if (*subTreePtr == upTree) + break; + subTreePtr = &(*subTreePtr)->next; + } + next = (*subTreePtr)->next; + *subTreePtr = upTree->subTrees; + upTree->subTrees->next = next; + } + + // Now delete the tree itself + upTree->subTrees = NULL; + upTree->comps = NULL; + uio_MountTree_delete(upTree); +} + +// pre: mountInfo exists in mountTree->pLocs (and hence in pLocs for +// every sub-tree) +static void +uio_mountTreeRemoveMountInfoRec(uio_MountTree *mountTree, + uio_MountInfo *mountInfo) { + uio_MountTree *subTree; + uio_MountTreeItem **itemPtr, *item; + + // recurse for all subTrees + for (subTree = mountTree->subTrees; subTree != NULL; + subTree = subTree->next) + uio_mountTreeRemoveMountInfoRec(subTree, mountInfo); + + // Find the mount info in this tree. + itemPtr = &mountTree->pLocs; + while (1) { + assert(*itemPtr != NULL); + // We know an item with the specified mountInfo + // must be here somewhere. + if ((*itemPtr)->mountInfo == mountInfo) { + // Found it. + break; + } + itemPtr = &(*itemPtr)->next; + } + + item = *itemPtr; + *itemPtr = item->next; + uio_MountTreeItem_delete(item); +} + +// Count the number of pLocs in a tree that leads to. +int +uio_mountTreeCountPLocs(const uio_MountTree *tree) { + int count; + uio_MountTreeItem *item; + + count = 0; + for (item = tree->pLocs; item != NULL; item = item->next) + count++; + return count; +} + +// resTree may point to top +// pPath may point to path +void +uio_findMountTree(uio_MountTree *top, const char *path, + uio_MountTree **resTree, const char **pPath) { + const char *start, *end, *pathFromTree; + uio_MountTree *tree, *sub; + uio_PathComp *comp; + + getFirstPath0Component(path, &start, &end); + tree = top; + while(1) { + if (*start == '\0') { + *resTree = tree; + *pPath = start; + return; + } + + pathFromTree = start; + sub = tree->subTrees; + while(1) { + if (sub == NULL) { + // No matching sub Dirs found. So we report back the current + // dir. + *resTree = tree; + *pPath = pathFromTree; + return; + } + comp = sub->comps; + if (strncmp(comp->name, start, end - start) == 0 && + comp->name[end - start] == '\0') + break; + sub = sub->next; + } + // Found a Sub dir which matches at least partially. + + while (1) { + getNextPath0Component(&start, &end); + comp = comp->next; + if (comp == NULL) + break; + if (*start == '\0' || + strncmp(comp->name, start, end - start) != 0 || + comp->name[end - start] != '\0') { + // either the path ends here, or the path in the tree does. + // either way, the last Tree is the one we want. + *resTree = tree; + *pPath = pathFromTree; + return; + } + } + // all components matched until the next MountTree + tree = sub; + } +} + +// finds the path to the MountInfo associated with a mountTreeItem +// given a path to the 'item' itself. +// 'item' is the mountTreeItem +// 'endComp' is the last PathComp leading to 'item' +// 'start' is the start of the path to the item +char * +uio_mountTreeItemRestPath(const uio_MountTreeItem *item, + uio_PathComp *endComp, const char *path) { + int i; + const char *pathPtr; + + i = item->depth; + while (i--) + endComp = endComp->up; + + pathPtr = path; + if (endComp != NULL) { + while (1) { + pathPtr += endComp->nameLen; + endComp = endComp->up; + if (endComp == NULL) + break; + pathPtr++; + // for a '/' + } + } + if (*path == '/') { + // / at the beginning of the path + pathPtr++; + } + if (*pathPtr == '/') { + // / at the end of the path + pathPtr++; + } +// return (char *) pathPtr; + // gives warning +// return *((char **)((void *) &pathPtr)); + // not portable + return (char *) unconst((const void *) pathPtr); +} + +void +uio_printMountTree(FILE *outStream, const uio_MountTree *tree, int indent) { + uio_MountTree *sub; + uio_PathComp *comp; + + fprintf(outStream, "("); + uio_printMountTreeItems(outStream, tree->pLocs); + fprintf(outStream, ")\n"); + for (sub = tree->subTrees; sub != NULL; sub = sub->next) { + int newIndent; + + newIndent = indent; + fprintf(outStream, "%*s", indent, ""); + for (comp = sub->comps; comp != NULL; comp = comp->next) { + fprintf(outStream, "/%s", comp->name); + newIndent += 1 + comp->nameLen; + } + fprintf(outStream, " "); + newIndent += 1; + uio_printMountTree(outStream, sub, newIndent); + } +} + +void +uio_printMountTreeItem(FILE *outStream, const uio_MountTreeItem *item) { + uio_printMountInfo(outStream, item->mountInfo); + fprintf(outStream, ":%d", item->depth); +} + +void +uio_printMountTreeItems(FILE *outStream, const uio_MountTreeItem *item) { + if (!item) + return; + while(1) { + uio_printMountTreeItem(outStream, item); + item = item->next; + if (item == NULL) + break; + fprintf(outStream, ", "); + } +} + +void +uio_printPathToMountTree(FILE *outStream, const uio_MountTree *tree) { + if (tree->upTree == NULL) { + fprintf(outStream, "/"); + } else + uio_printPathToComp(outStream, tree->lastComp); +} + +void +uio_printMountInfo(FILE *outStream, const uio_MountInfo *mountInfo) { + uio_FileSystemInfo *fsInfo; + + fsInfo = uio_getFileSystemInfo(mountInfo->fsID); + fprintf(outStream, "%s:/%s", fsInfo->name, mountInfo->dirName); +} + +static void +uio_printMount(FILE *outStream, const uio_MountInfo *mountInfo) { + uio_FileSystemInfo *fsInfo; + + fsInfo = uio_getFileSystemInfo(mountInfo->fsID); + fprintf(outStream, "???:%s on ", mountInfo->dirName); + uio_printPathToMountTree(outStream, mountInfo->mountTree); + fprintf(outStream, " type %s (", fsInfo->name); + if (mountInfo->flags & uio_MOUNT_RDONLY) { + fprintf(outStream, "ro"); + } else + fprintf(outStream, "rw"); + fprintf(outStream, ")\n"); +} + +void +uio_printMounts(FILE *outStream, const uio_Repository *repository) { + int i; + + for (i = 0; i < repository->numMounts; i++) { + uio_printMount(outStream, repository->mounts[i]); + } +} + + +// *** uio_MountTree*** // + +static inline uio_MountTree * +uio_MountTree_new(uio_MountTree *subTrees, uio_MountTreeItem *pLocs, + uio_MountTree *upTree, uio_PathComp *comps, uio_PathComp *lastComp, + uio_MountTree *next) { + uio_MountTree *result; + + result = uio_MountTree_alloc(); + result->subTrees = subTrees; + result->pLocs = pLocs; + result->upTree = upTree; + result->comps = comps; + result->lastComp = lastComp; + result->next = next; + return result; +} + +void +uio_MountTree_delete(uio_MountTree *tree) { + uio_MountTree *subTree, *nextTree; + uio_MountTreeItem *item, *nextItem; + + subTree = tree->subTrees; + while (subTree != NULL) { + nextTree = subTree->next; + uio_MountTree_delete(subTree); + subTree = nextTree; + } + + item = tree->pLocs; + while (item != NULL) { + nextItem = item->next; + uio_MountTreeItem_delete(item); + item = nextItem; + } + + if (tree->comps != NULL) + uio_PathComp_delete(tree->comps); + + uio_MountTree_free(tree); +} + +static inline uio_MountTree * +uio_MountTree_alloc(void) { + uio_MountTree *result = uio_malloc(sizeof (uio_MountTree)); +#ifdef uio_MEM_DEBUG + uio_MemDebug_debugAlloc(uio_MountTree, (void *) result); +#endif + return result; +} + +static inline void +uio_MountTree_free(uio_MountTree *mountTree) { +#ifdef uio_MEM_DEBUG + uio_MemDebug_debugFree(uio_MountTree, (void *) mountTree); +#endif + uio_free(mountTree); +} + + +// *** uio_MountTreeItem *** // + +static inline uio_MountTreeItem * +uio_MountTree_newItem(uio_MountInfo *mountInfo, int depth, + uio_MountTreeItem *next) { + uio_MountTreeItem *result; + + result = uio_MountTreeItem_alloc(); + result->mountInfo = mountInfo; + result->depth = depth; + result->next = next; + return result; +} + +static inline void +uio_MountTreeItem_delete(uio_MountTreeItem *item) { + uio_MountTreeItem_free(item); +} + +static inline uio_MountTreeItem * +uio_MountTreeItem_alloc(void) { + uio_MountTreeItem *result = uio_malloc(sizeof (uio_MountTreeItem)); +#ifdef uio_MEM_DEBUG + uio_MemDebug_debugAlloc(uio_MountTreeItem, (void *) result); +#endif + return result; +} + +static inline void +uio_MountTreeItem_free(uio_MountTreeItem *mountTreeItem) { +#ifdef uio_MEM_DEBUG + uio_MemDebug_debugFree(uio_MountTreeItem, (void *) mountTreeItem); +#endif + uio_free(mountTreeItem); +} + + +// *** uio_MountInfo *** // + +uio_MountInfo * +uio_MountInfo_new(uio_FileSystemID fsID, uio_MountTree *mountTree, + uio_PDirHandle *pDirHandle, char *dirName, uio_AutoMount **autoMount, + uio_MountHandle *mountHandle, int flags) { + uio_MountInfo *result; + + result = uio_MountInfo_alloc(); + result->fsID = fsID; + result->mountTree = mountTree; + result->pDirHandle = pDirHandle; + result->dirName = dirName; + result->autoMount = autoMount; + result->mountHandle = mountHandle; + result->flags = flags; + return result; +} + +void +uio_MountInfo_delete(uio_MountInfo *mountInfo) { + uio_free(mountInfo->dirName); + uio_PDirHandle_unref(mountInfo->pDirHandle); + uio_MountInfo_free(mountInfo); +} + +static inline uio_MountInfo * +uio_MountInfo_alloc(void) { + uio_MountInfo *result = uio_malloc(sizeof (uio_MountInfo)); +#ifdef uio_MEM_DEBUG + uio_MemDebug_debugAlloc(uio_MountInfo, (void *) result); +#endif + return result; +} + +static inline void +uio_MountInfo_free(uio_MountInfo *mountInfo) { +#ifdef uio_MEM_DEBUG + uio_MemDebug_debugFree(uio_MountInfo, (void *) mountInfo); +#endif + uio_free(mountInfo); +} + + |