stos: ob: Add directory object operations
This commit adds operations for appending directories and top-level lookups. Signed-off-by: Chloe M. <chloe@mensia.org>
This commit is contained in:
@@ -35,6 +35,7 @@ typedef enum {
|
|||||||
* @Type: Object type
|
* @Type: Object type
|
||||||
* @Data: Object data
|
* @Data: Object data
|
||||||
* @CacheNext: Used when reclaiming object
|
* @CacheNext: Used when reclaiming object
|
||||||
|
* @DirecNext: Directory link
|
||||||
*/
|
*/
|
||||||
typedef struct _ST_OBJECT {
|
typedef struct _ST_OBJECT {
|
||||||
CHAR Name[OBJECT_NAMESZ];
|
CHAR Name[OBJECT_NAMESZ];
|
||||||
@@ -42,6 +43,7 @@ typedef struct _ST_OBJECT {
|
|||||||
OBJECT_TYPE Type;
|
OBJECT_TYPE Type;
|
||||||
VOID *Data;
|
VOID *Data;
|
||||||
struct _ST_OBJECT *CacheNext;
|
struct _ST_OBJECT *CacheNext;
|
||||||
|
struct _ST_OBJECT *DirecNext;
|
||||||
} ST_OBJECT;
|
} ST_OBJECT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -66,6 +68,14 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
ST_STATUS ObCreateDirectory(const CHAR *Name, ST_OBJECT **Result);
|
ST_STATUS ObCreateDirectory(const CHAR *Name, ST_OBJECT **Result);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Append an object to a directory
|
||||||
|
*
|
||||||
|
* @DirecParent: Parent of directory to append to
|
||||||
|
* @Object: Object to append to directory
|
||||||
|
*/
|
||||||
|
ST_STATUS ObAppendDirectory(ST_OBJECT *DirecParent, ST_OBJECT *Object);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate and create a new objec
|
* Allocate and create a new objec
|
||||||
*
|
*
|
||||||
@@ -84,6 +94,15 @@ ST_STATUS ObCreateObject(
|
|||||||
*/
|
*/
|
||||||
VOID ObInitManager(VOID);
|
VOID ObInitManager(VOID);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up an object from a parent directory
|
||||||
|
*
|
||||||
|
* @Parent: Parent directly to look up from
|
||||||
|
* @Name: Name of object to lookup
|
||||||
|
* @Result: Result is written here
|
||||||
|
*/
|
||||||
|
ST_STATUS ObLookupFromTop(ST_OBJECT *Parent, const CHAR *Name, ST_OBJECT **Result);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reclaim an object after use, if its reference count is > 1, simply
|
* Reclaim an object after use, if its reference count is > 1, simply
|
||||||
* bump it down. Once it hits zero, the object is returned to the cache.
|
* bump it down. Once it hits zero, the object is returned to the cache.
|
||||||
|
|||||||
@@ -104,3 +104,83 @@ ObReclaimObject(ST_OBJECT *Object)
|
|||||||
ObReclaimToCache(&gObCache, Object);
|
ObReclaimToCache(&gObCache, Object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ST_STATUS
|
||||||
|
ObAppendDirectory(ST_OBJECT *DirecParent, ST_OBJECT *Object)
|
||||||
|
{
|
||||||
|
OBJECT_DIRECTORY *Directory;
|
||||||
|
ST_OBJECT *Last;
|
||||||
|
|
||||||
|
if (DirecParent == NULL || Object == NULL) {
|
||||||
|
return STATUS_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DirecParent->Type != OBJECT_TYPE_DIRECTORY) {
|
||||||
|
return STATUS_NOT_DIRECTORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory = DirecParent->Data;
|
||||||
|
if (Directory == NULL) {
|
||||||
|
return STATUS_IO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Place lock here */
|
||||||
|
if (Directory->First == NULL || Directory->Last == NULL) {
|
||||||
|
Directory->First = Object;
|
||||||
|
Directory->Last = Object;
|
||||||
|
} else {
|
||||||
|
Last = Directory->Last;
|
||||||
|
Last->DirecNext = Object;
|
||||||
|
Directory->Last = Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ST_STATUS
|
||||||
|
ObLookupFromTop(ST_OBJECT *Parent, const CHAR *Name, ST_OBJECT **Result)
|
||||||
|
{
|
||||||
|
ST_OBJECT *Entry;
|
||||||
|
OBJECT_DIRECTORY *ParentDirec;
|
||||||
|
USIZE NameLen;
|
||||||
|
|
||||||
|
if (Parent == NULL || Name == NULL) {
|
||||||
|
return STATUS_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Result == NULL) {
|
||||||
|
return STATUS_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Must be a directory */
|
||||||
|
if (Parent->Type != OBJECT_TYPE_DIRECTORY) {
|
||||||
|
return STATUS_NOT_DIRECTORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParentDirec = Parent->Data;
|
||||||
|
if (ParentDirec == NULL) {
|
||||||
|
return STATUS_IO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry = ParentDirec->First;
|
||||||
|
NameLen = RtlStrLen(Name);
|
||||||
|
if (NameLen >= OBJECT_NAMESZ - 1) {
|
||||||
|
return STATUS_NAME_TOO_LONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (Entry != NULL) {
|
||||||
|
if (*Entry->Name != *Name) {
|
||||||
|
Entry = Entry->DirecNext;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RtlMemCmp(Entry->Name, Name, NameLen) == 0) {
|
||||||
|
*Result = Entry;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry = Entry->DirecNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user