/*
- * AcessMicro VFS
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * vfs/fs/root.c
* - Root Filesystem Driver
+ *
+ * TODO: Restrict to directories+symlinks only
*/
#define DEBUG 0
#include <acess.h>
// === CONSTANTS ===
#define MAX_FILES 64
-#define MAX_FILE_SIZE 1024
+#define MAX_FILE_SIZE 10*1024*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);
-size_t Root_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
-size_t Root_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
+tVFS_Node *Root_GetByINode(tVFS_Node *RootNode, Uint64 Inode);
+tVFS_Node *Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node *Root_FindDir(tVFS_Node *Node, const char *Name, Uint Flags);
+ int Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
+size_t Root_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags);
+size_t Root_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags);
tRamFS_File *Root_int_AllocFile(void);
// === GLOBALS ===
tVFS_Driver gRootFS_Info = {
- "rootfs", 0, Root_InitDevice, NULL, NULL
+ .Name = "rootfs",
+ .InitDevice = Root_InitDevice,
+ .GetNodeFromINode = Root_GetByINode
};
tRamFS_File RootFS_Files[MAX_FILES];
tVFS_ACL RootFS_DirACLs[3] = {
{{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,0}, {0,VFS_PERM_ALL^VFS_PERM_EXEC}}, // Owner (Root)
+ {{1,0}, {0,VFS_PERM_ALL^VFS_PERM_EXEC}}, // Group (Root)
{{0,-1}, {0,VFS_PERM_READ}} // World (Nobody)
};
tVFS_NodeType gRootFS_DirType = {
root->Node.NumACLs = 3;
root->Node.ACLs = RootFS_DirACLs;
+ root->Node.Flags = VFS_FFLAG_DIRECTORY;
root->Node.Type = &gRootFS_DirType;
return &root->Node;
}
+tVFS_Node *Root_GetByINode(tVFS_Node *RootNode, Uint64 Inode)
+{
+ if( Inode >= MAX_FILES )
+ return NULL;
+ if( RootFS_Files[Inode].Name[0] == '\0' )
+ return NULL;
+ Debug("Root_GetByINode: (%llx) = '%s' %p",
+ Inode,
+ RootFS_Files[Inode].Name, &RootFS_Files[Inode].Node
+ );
+ return &RootFS_Files[Inode].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)
+tVFS_Node *Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
{
tRamFS_File *parent = Node->ImplPtr;
tRamFS_File *child;
ENTER("pNode sName xFlags", Node, Name, Flags);
LOG("Sanity check name length - %i > %i", strlen(Name)+1, sizeof(child->Name));
- if(strlen(Name) + 1 > sizeof(child->Name))
- LEAVE_RET('i', 0);
+ if(strlen(Name) + 1 > sizeof(child->Name)) {
+ errno = EINVAL;
+ LEAVE_RET('n', NULL);
+ }
// 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) {
LOG("Duplicate");
- LEAVE('i', 0);
- return 0;
+ errno = EEXIST;
+ LEAVE_RET('n', NULL);
}
}
child = Root_int_AllocFile();
- memset(child, 0, sizeof(tRamFS_File));
strcpy(child->Name, Name);
LOG("Name = '%s'", child->Name);
parent->Node.Size ++;
- LEAVE('i', 1);
- return 1;
+ LEAVE('n', &child->Node);
+ return &child->Node;
}
/**
* \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)
+tVFS_Node *Root_FindDir(tVFS_Node *Node, const char *Name, Uint Flags)
{
tRamFS_File *parent = Node->ImplPtr;
tRamFS_File *child = parent->Data.FirstChild;
* \fn char *Root_ReadDir(tVFS_Node *Node, int Pos)
* \brief Get an entry from the filesystem
*/
-char *Root_ReadDir(tVFS_Node *Node, int Pos)
+int Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
tRamFS_File *parent = Node->ImplPtr;
tRamFS_File *child = parent->Data.FirstChild;
for( ; child && Pos--; child = child->Next ) ;
- if(child) return strdup(child->Name);
+ if(child) {
+ strncpy(Dest, child->Name, FILENAME_MAX);
+ return 0;
+ }
- return NULL;
+ return -ENOENT;
}
/**
* \brief Read from a file in the root directory
*/
-size_t Root_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
+size_t Root_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags)
{
tRamFS_File *file = Node->ImplPtr;
/**
* \brief Write to a file in the root directory
*/
-size_t Root_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)
+size_t Root_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags)
{
tRamFS_File *file = Node->ImplPtr;
if(Offset + Length > MAX_FILE_SIZE)
{
Length = MAX_FILE_SIZE - Offset;
+ ASSERTC(Length, <=, MAX_FILE_SIZE);
}
- LOG("Buffer = '%.*s'", (int)Length, Buffer);
+ LOG("Length = %x", Length);
// Check if buffer needs to be expanded
if(Offset + Length > Node->Size)
{
- void *tmp = realloc( file->Data.Bytes, Offset + Length );
+ size_t newsize = Offset + Length;
+ void *tmp = realloc( file->Data.Bytes, newsize );
if(tmp == NULL) {
- Warning("Root_Write - Increasing buffer size failed");
+ Warning("Root_Write - Increasing buffer size failed (0x%x)",
+ newsize);
LEAVE('i', -1);
return -1;
}
{
if( RootFS_Files[i].Name[0] == '\0' )
{
+ RootFS_Files[i].Node.Inode = i;
return &RootFS_Files[i];
}
}