X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fvfs%2Ffs%2Froot.c;fp=KernelLand%2FKernel%2Fvfs%2Ffs%2Froot.c;h=9fa1732b9391f054dc84ba20b57fb055590cdb59;hb=48743e39650eb1ef988380e9d95f27fd40d3a9ce;hp=0000000000000000000000000000000000000000;hpb=a2495c6ea4f4cab16b5d339ae511428e92e89e73;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/vfs/fs/root.c b/KernelLand/Kernel/vfs/fs/root.c new file mode 100644 index 00000000..9fa1732b --- /dev/null +++ b/KernelLand/Kernel/vfs/fs/root.c @@ -0,0 +1,255 @@ +/* + * AcessMicro VFS + * - Root Filesystem Driver + */ +#define DEBUG 0 +#include +#include +#include + +// === CONSTANTS === +#define MAX_FILES 64 +#define MAX_FILE_SIZE 1024 + +// === PROTOTYPES === +tVFS_Node *Root_InitDevice(const char *Device, const char **Options); + int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags); +tVFS_Node *Root_FindDir(tVFS_Node *Node, const char *Name); +char *Root_ReadDir(tVFS_Node *Node, int Pos); +Uint64 Root_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); +Uint64 Root_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer); +tRamFS_File *Root_int_AllocFile(void); + +// === GLOBALS === +tVFS_Driver gRootFS_Info = { + "rootfs", 0, Root_InitDevice, NULL, NULL + }; +tRamFS_File RootFS_Files[MAX_FILES]; +tVFS_ACL RootFS_DirACLs[3] = { + {{0,0}, {0,VFS_PERM_ALL}}, // Owner (Root) + {{1,0}, {0,VFS_PERM_ALL}}, // Group (Root) + {{0,-1}, {0,VFS_PERM_ALL^VFS_PERM_WRITE}} // World (Nobody) +}; +tVFS_ACL RootFS_FileACLs[3] = { + {{0,0}, {0,VFS_PERM_ALL^VFS_PERM_EXECUTE}}, // Owner (Root) + {{1,0}, {0,VFS_PERM_ALL^VFS_PERM_EXECUTE}}, // Group (Root) + {{0,-1}, {0,VFS_PERM_READ}} // World (Nobody) +}; +tVFS_NodeType gRootFS_DirType = { + .TypeName = "RootFS-Dir", + .ReadDir = Root_ReadDir, + .FindDir = Root_FindDir, + .MkNod = Root_MkNod +}; +tVFS_NodeType gRootFS_FileType = { + .TypeName = "RootFS-File", + .Read = Root_Read, + .Write = Root_Write, +}; + +// === CODE === +/** + * \brief Initialise the root filesystem + */ +tVFS_Node *Root_InitDevice(const char *Device, const char **Options) +{ + tRamFS_File *root; + if(strcmp(Device, "root") != 0) { + return NULL; + } + + // Create Root Node + root = &RootFS_Files[0]; + + root->Node.ImplPtr = root; + + root->Node.CTime + = root->Node.MTime + = root->Node.ATime = now(); + root->Node.NumACLs = 3; + root->Node.ACLs = RootFS_DirACLs; + + root->Node.Type = &gRootFS_DirType; + + return &root->Node; +} + +/** + * \fn int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags) + * \brief Create an entry in the root directory + */ +int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags) +{ + tRamFS_File *parent = Node->ImplPtr; + tRamFS_File *child; + tRamFS_File *prev = (tRamFS_File *) &parent->Data.FirstChild; + + ENTER("pNode sName xFlags", Node, Name, Flags); + + LOG("%i > %i", strlen(Name)+1, sizeof(child->Name)); + if(strlen(Name) + 1 > sizeof(child->Name)) + LEAVE_RET('i', 0); + + // Find last child, while we're at it, check for duplication + for( child = parent->Data.FirstChild; child; prev = child, child = child->Next ) + { + if(strcmp(child->Name, Name) == 0) { + LEAVE('i', 0); + return 0; + } + } + + child = Root_int_AllocFile(); + memset(child, 0, sizeof(tRamFS_File)); + + strcpy(child->Name, Name); + + child->Parent = parent; + child->Next = NULL; + child->Data.FirstChild = NULL; + + child->Node.ImplPtr = child; + child->Node.Flags = Flags; + child->Node.NumACLs = 3; + child->Node.Size = 0; + + if(Flags & VFS_FFLAG_DIRECTORY) + { + child->Node.ACLs = RootFS_DirACLs; + child->Node.Type = &gRootFS_DirType; + } else { + if(Flags & VFS_FFLAG_SYMLINK) + child->Node.ACLs = RootFS_DirACLs; + else + child->Node.ACLs = RootFS_FileACLs; + child->Node.Type = &gRootFS_FileType; + } + + prev->Next = child; + + parent->Node.Size ++; + + LEAVE('i', 1); + return 1; +} + +/** + * \fn tVFS_Node *Root_FindDir(tVFS_Node *Node, const char *Name) + * \brief Find an entry in the filesystem + */ +tVFS_Node *Root_FindDir(tVFS_Node *Node, const char *Name) +{ + tRamFS_File *parent = Node->ImplPtr; + tRamFS_File *child = parent->Data.FirstChild; + + //Log("Root_FindDir: (Node=%p, Name='%s')", Node, Name); + + for(;child;child = child->Next) + { + //Log(" Root_FindDir: strcmp('%s', '%s')", child->Node.Name, Name); + if(strcmp(child->Name, Name) == 0) return &child->Node; + } + + return NULL; +} + +/** + * \fn char *Root_ReadDir(tVFS_Node *Node, int Pos) + * \brief Get an entry from the filesystem + */ +char *Root_ReadDir(tVFS_Node *Node, int Pos) +{ + tRamFS_File *parent = Node->ImplPtr; + tRamFS_File *child = parent->Data.FirstChild; + + for( ; child && Pos--; child = child->Next ) ; + + if(child) return strdup(child->Name); + + return NULL; +} + +/** + * \fn Uint64 Root_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) + * \brief Read from a file in the root directory + */ +Uint64 Root_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +{ + tRamFS_File *file = Node->ImplPtr; + ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); + + if(Offset > Node->Size) { + LEAVE('i', 0); + return 0; + } + if(Length > Node->Size) Length = Node->Size; + + if(Offset+Length > Node->Size) + Length = Node->Size - Offset; + + memcpy(Buffer, file->Data.Bytes+Offset, Length); + LOG("Buffer = '%.*s'", (int)Length, Buffer); + + LEAVE('i', Length); + return Length; +} + +/** + * \fn Uint64 Root_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) + * \brief Write to a file in the root directory + */ +Uint64 Root_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer) +{ + tRamFS_File *file = Node->ImplPtr; + + ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); + + if(Offset > Node->Size) { + LEAVE('i', -1); + return -1; + } + + if(Offset + Length > MAX_FILE_SIZE) + { + Length = MAX_FILE_SIZE - Offset; + } + + LOG("Buffer = '%.*s'", (int)Length, Buffer); + + // Check if buffer needs to be expanded + if(Offset + Length > Node->Size) + { + void *tmp = realloc( file->Data.Bytes, Offset + Length ); + if(tmp == NULL) { + Warning("Root_Write - Increasing buffer size failed"); + LEAVE('i', -1); + return -1; + } + file->Data.Bytes = tmp; + Node->Size = Offset + Length; + LOG("Expanded buffer to %i bytes", (int)Node->Size); + } + + memcpy(file->Data.Bytes+Offset, Buffer, Length); + LOG("File - '%.*s'", Node->Size, file->Data.Bytes); + + LEAVE('i', Length); + return Length; +} + +/** + * \fn tRamFS_File *Root_int_AllocFile(void) + * \brief Allocates a file from the pool + */ +tRamFS_File *Root_int_AllocFile(void) +{ + int i; + for( i = 0; i < MAX_FILES; i ++ ) + { + if( RootFS_Files[i].Name[0] == '\0' ) + { + return &RootFS_Files[i]; + } + } + return NULL; +}