Usermode/libaxwin4 - Handle demarshal failure
[tpg/acess2.git] / KernelLand / Modules / Filesystems / Ext2 / ext2.c
index 4d13f1e..eacf87b 100644 (file)
 tVFS_Node      *Ext2_InitDevice(const char *Device, const char **Options);\r
 void   Ext2_Unmount(tVFS_Node *Node);\r
 void   Ext2_CloseFile(tVFS_Node *Node);\r
+tVFS_Node      *Ext2_GetNodeFromINode(tVFS_Node *RootNode, Uint64 Inode);\r
 // - Internal Helpers\r
  int   Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode);\r
+void   Ext2_int_DumpInode(tExt2_Disk *Disk, Uint32 InodeID, tExt2_Inode *Inode);\r
 Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);\r
 Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent);\r
 void   Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode);\r
@@ -37,7 +39,7 @@ tVFS_Driver   gExt2_FSInfo = {
        .Detect = Ext2_Detect,\r
        .InitDevice = Ext2_InitDevice,\r
        .Unmount = Ext2_Unmount,\r
-       .GetNodeFromINode = NULL\r
+       .GetNodeFromINode = Ext2_GetNodeFromINode\r
        };\r
 \r
 // === CODE ===\r
@@ -96,7 +98,6 @@ tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)
         int    fd;\r
         int    groupCount;\r
        tExt2_SuperBlock        sb;\r
-       tExt2_Inode     inode;\r
        \r
        ENTER("sDevice pOptions", Device, Options);\r
        \r
@@ -139,7 +140,7 @@ tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)
        disk->GroupCount = groupCount;\r
        \r
        // Get an inode cache handle\r
-       disk->CacheID = Inode_GetHandle();\r
+       disk->CacheID = Inode_GetHandle(NULL);\r
        \r
        // Get Block Size\r
        if( sb.s_log_block_size > MAX_BLOCK_LOG_SIZE ) {\r
@@ -169,7 +170,7 @@ tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)
        LOG(".bg_inode_table = 0x%x", disk->Groups[1].bg_inode_table);\r
        \r
        // Get root Inode\r
-       Ext2_int_ReadInode(disk, 2, &inode);\r
+       Ext2_int_ReadInode(disk, 2, &disk->RootInode);\r
        \r
        // Create Root Node\r
        memset(&disk->RootNode, 0, sizeof(tVFS_Node));\r
@@ -181,14 +182,14 @@ tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)
        disk->RootNode.Type = &gExt2_DirType;\r
        \r
        // Complete root node\r
-       disk->RootNode.UID = inode.i_uid;\r
-       disk->RootNode.GID = inode.i_gid;\r
+       disk->RootNode.UID = disk->RootInode.i_uid;\r
+       disk->RootNode.GID = disk->RootInode.i_gid;\r
        disk->RootNode.NumACLs = 1;\r
        disk->RootNode.ACLs = &gVFS_ACL_EveryoneRW;\r
        \r
        #if DEBUG\r
-       LOG("inode.i_size = 0x%x", inode.i_size);\r
-       LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);\r
+       LOG("inode.i_size = 0x%x", disk->RootInode.i_size);\r
+       LOG("inode.i_block[0] = 0x%x", disk->RootInode.i_block[0]);\r
        #endif\r
        \r
        LEAVE('p', &disk->RootNode);\r
@@ -260,6 +261,11 @@ void Ext2_CloseFile(tVFS_Node *Node)
        return ;\r
 }\r
 \r
+tVFS_Node *Ext2_GetNodeFromINode(tVFS_Node *RootNode, Uint64 Inode)\r
+{\r
+       return Ext2_int_CreateNode(RootNode->ImplPtr, Inode);\r
+}\r
+\r
 //==================================\r
 //=       INTERNAL FUNCTIONS       =\r
 //==================================\r
@@ -304,7 +310,9 @@ int Ext2_int_WriteInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode)
                LEAVE('i', 0);\r
                return 0;\r
        }\r
-       \r
+\r
+       Ext2_int_DumpInode(Disk, InodeId, Inode);       \r
+\r
        InodeId --;     // Inodes are numbered starting at 1\r
        \r
        group = InodeId / Disk->SuperBlock.s_inodes_per_group;\r
@@ -329,112 +337,134 @@ int Ext2_int_WriteInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode)
  */\r
 tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)\r
 {\r
-       tExt2_Inode     inode;\r
-       tVFS_Node       retNode;\r
-       tVFS_Node       *tmpNode;\r
-       \r
-       if( !Ext2_int_ReadInode(Disk, InodeID, &inode) )\r
+       struct {\r
+               tVFS_Node       retNode;\r
+               tExt2_Inode     inode;\r
+       } data;\r
+       tVFS_Node       *node = &data.retNode;\r
+       tExt2_Inode     *in = &data.inode;\r
+       \r
+       if( !Ext2_int_ReadInode(Disk, InodeID, &data.inode) )\r
                return NULL;\r
        \r
-       if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )\r
-               return tmpNode;\r
+       if( (node = Inode_GetCache(Disk->CacheID, InodeID)) )\r
+               return node;\r
+       node = &data.retNode;\r
 \r
-       memset(&retNode, 0, sizeof(retNode));   \r
+       memset(node, 0, sizeof(*node));\r
        \r
        // Set identifiers\r
-       retNode.Inode = InodeID;\r
-       retNode.ImplPtr = Disk;\r
-       retNode.ImplInt = inode.i_links_count;\r
-       if( inode.i_links_count == 0 ) {\r
+       node->Inode = InodeID;\r
+       node->ImplPtr = Disk;\r
+       node->ImplInt = in->i_links_count;\r
+       if( in->i_links_count == 0 ) {\r
                Log_Notice("Ext2", "Inode %p:%x is not referenced, bug?", Disk, InodeID);\r
        }\r
        \r
        // Set file length\r
-       retNode.Size = inode.i_size;\r
+       node->Size = in->i_size;\r
        \r
        // Set Access Permissions\r
-       retNode.UID = inode.i_uid;\r
-       retNode.GID = inode.i_gid;\r
-       retNode.NumACLs = 3;\r
-       retNode.ACLs = VFS_UnixToAcessACL(inode.i_mode & 0777, inode.i_uid, inode.i_gid);\r
+       node->UID = in->i_uid;\r
+       node->GID = in->i_gid;\r
+       node->NumACLs = 3;\r
+       node->ACLs = VFS_UnixToAcessACL(in->i_mode & 0777, in->i_uid, in->i_gid);\r
        \r
        //  Set Function Pointers\r
-       retNode.Type = &gExt2_FileType;\r
+       node->Type = &gExt2_FileType;\r
        \r
-       switch(inode.i_mode & EXT2_S_IFMT)\r
+       switch(in->i_mode & EXT2_S_IFMT)\r
        {\r
        // Symbolic Link\r
        case EXT2_S_IFLNK:\r
-               retNode.Flags = VFS_FFLAG_SYMLINK;\r
+               node->Flags = VFS_FFLAG_SYMLINK;\r
                break;\r
        // Regular File\r
        case EXT2_S_IFREG:\r
-               retNode.Flags = 0;\r
-               retNode.Size |= (Uint64)inode.i_dir_acl << 32;\r
+               node->Flags = 0;\r
+               node->Size |= (Uint64)in->i_dir_acl << 32;\r
                break;\r
        // Directory\r
        case EXT2_S_IFDIR:\r
-               retNode.Type = &gExt2_DirType;\r
-               retNode.Flags = VFS_FFLAG_DIRECTORY;\r
-               retNode.Data = calloc( sizeof(Uint16), DivUp(retNode.Size, Disk->BlockSize) );\r
+               node->Type = &gExt2_DirType;\r
+               node->Flags = VFS_FFLAG_DIRECTORY;\r
+               node->Data = calloc( sizeof(Uint16), DivUp(node->Size, Disk->BlockSize) );\r
                break;\r
        // Unknown, Write protect it to be safe \r
        default:\r
-               retNode.Flags = VFS_FFLAG_READONLY;\r
+               node->Flags = VFS_FFLAG_READONLY;\r
                break;\r
        }\r
        \r
        // Set Timestamps\r
-       retNode.ATime = inode.i_atime * 1000;\r
-       retNode.MTime = inode.i_mtime * 1000;\r
-       retNode.CTime = inode.i_ctime * 1000;\r
+       node->ATime = in->i_atime * 1000;\r
+       node->MTime = in->i_mtime * 1000;\r
+       node->CTime = in->i_ctime * 1000;\r
        \r
        // Save in node cache and return saved node\r
-       return Inode_CacheNode(Disk->CacheID, &retNode);\r
+       return Inode_CacheNodeEx(Disk->CacheID, &data.retNode, sizeof(data));\r
 }\r
 \r
 int Ext2_int_WritebackNode(tExt2_Disk *Disk, tVFS_Node *Node)\r
 {\r
-       tExt2_Inode     inode;\r
+       tExt2_Inode     *inode = (void*)(Node+1);\r
 \r
        if( Disk != Node->ImplPtr ) {\r
                Log_Error("Ext2", "Ext2_int_WritebackNode - Disk != Node->ImplPtr");\r
                return -1;\r
        }\r
-       \r
+\r
        if( Node->Flags & VFS_FFLAG_SYMLINK ) {\r
-               inode.i_mode = EXT2_S_IFLNK;\r
+               inode->i_mode = EXT2_S_IFLNK;\r
        }\r
        else if( Node->Flags & VFS_FFLAG_DIRECTORY ) {\r
-               inode.i_mode = EXT2_S_IFDIR;\r
+               inode->i_mode = EXT2_S_IFDIR;\r
        }\r
        else if( Node->Flags & VFS_FFLAG_READONLY ) {\r
                Log_Notice("Ext2", "Not writing back readonly inode %p:%x", Disk, Node->Inode);\r
                return 1;\r
        }\r
        else {\r
-               inode.i_mode = EXT2_S_IFREG;\r
-               inode.i_dir_acl = Node->Size >> 32;\r
+               inode->i_mode = EXT2_S_IFREG;\r
+               inode->i_dir_acl = Node->Size >> 32;\r
        }\r
 \r
-       inode.i_size = Node->Size & 0xFFFFFFFF;\r
-       inode.i_links_count = Node->ImplInt;\r
+       inode->i_size = Node->Size & 0xFFFFFFFF;\r
+       inode->i_links_count = Node->ImplInt;\r
 \r
-       inode.i_uid = Node->UID;\r
-       inode.i_gid = Node->GID;\r
+       inode->i_uid = Node->UID;\r
+       inode->i_gid = Node->GID;\r
 \r
-       inode.i_atime = Node->ATime / 1000;\r
-       inode.i_mtime = Node->MTime / 1000;\r
-       inode.i_ctime = Node->CTime / 1000;\r
+       inode->i_atime = Node->ATime / 1000;\r
+       inode->i_mtime = Node->MTime / 1000;\r
+       inode->i_ctime = Node->CTime / 1000;\r
 \r
        // TODO: Compact ACLs into unix mode\r
        Log_Warning("Ext2", "TODO: Support converting Acess ACLs into unix modes");\r
+       inode->i_mode |= 777;\r
 \r
-       Ext2_int_WriteInode(Disk, Node->Inode, &inode);\r
+       Ext2_int_WriteInode(Disk, Node->Inode, inode);\r
 \r
        return 0;\r
 }\r
 \r
+void Ext2_int_DumpInode(tExt2_Disk *Disk, Uint32 InodeID, tExt2_Inode *Inode)\r
+{\r
+       LOG("%p[Inode %i] = {", Disk, InodeID);\r
+       LOG(" .i_mode = 0%04o", Inode->i_mode);\r
+       LOG(" .i_uid:i_gid = %i:%i", Inode->i_uid, Inode->i_gid);\r
+       LOG(" .i_size = 0x%x", Inode->i_size);\r
+       LOG(" .i_block[0:3] = {0x%x,0x%x,0x%x,0x%x}",\r
+               Inode->i_block[0], Inode->i_block[1], Inode->i_block[2], Inode->i_block[3]);\r
+       LOG(" .i_block[4:7] = {0x%x,0x%x,0x%x,0x%x}",\r
+               Inode->i_block[4], Inode->i_block[5], Inode->i_block[6], Inode->i_block[7]);\r
+       LOG(" .i_block[8:11] = {0x%x,0x%x,0x%x,0x%x}",\r
+               Inode->i_block[8], Inode->i_block[6], Inode->i_block[10], Inode->i_block[11]);\r
+       LOG(" .i_block[12:14] = {0x%x,0x%x,0x%x}",\r
+               Inode->i_block[12], Inode->i_block[13], Inode->i_block[14]);\r
+       LOG("}");\r
+}\r
+\r
 /**\r
  * \fn Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)\r
  * \brief Get the address of a block from an inode's list\r
@@ -529,7 +559,7 @@ Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)
                VFS_ReadAt(Disk->FD, Disk->BlockSize*bg->bg_inode_bitmap+ofs, sector_size, buf);\r
 \r
                int byte, bit;\r
-               for( byte = 0; byte < sector_size && buf[byte] != 0xFF; byte ++ )\r
+               for( byte = 0; byte < sector_size && buf[byte] == 0xFF; byte ++ )\r
                        ;\r
                if( byte < sector_size )\r
                {\r
@@ -577,6 +607,14 @@ void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)
        // Update Primary\r
        VFS_WriteAt(Disk->FD, 1024, 1024, &Disk->SuperBlock);\r
        \r
+       // - Update block groups while we're at it\r
+       VFS_WriteAt(\r
+               Disk->FD,\r
+               Disk->SuperBlock.s_first_data_block * Disk->BlockSize + 1024,\r
+               sizeof(tExt2_Group)*Disk->GroupCount,\r
+               Disk->Groups\r
+               );\r
+       \r
        // Secondaries\r
        // at Block Group 1, 3^n, 5^n, 7^n\r
        \r

UCC git Repository :: git.ucc.asn.au