Modules/Ext2 - Fixed not unlocking node lock for non-cached node (e.g. root)
[tpg/acess2.git] / KernelLand / Modules / Filesystems / Ext2 / ext2.c
index 7c4bf97..460c4fb 100644 (file)
@@ -1,14 +1,12 @@
 /*\r
- * Acess OS\r
- * Ext2 Driver Version 1\r
+ * Acess2 Ext2 Driver\r
+ * - By John Hodge (thePowersGang)\r
+ *\r
+ * ext2.c\r
+ * - Driver core\r
  */\r
-/**\r
- * \file fs/ext2.c\r
- * \brief Second Extended Filesystem Driver\r
- * \todo Implement file full write support\r
- */\r
-#define DEBUG  1\r
-#define VERBOSE        0\r
+#define DEBUG  0\r
+#define VERSION        VER2(0,90)\r
 #include "ext2_common.h"\r
 #include <modules.h>\r
 \r
@@ -17,22 +15,29 @@ extern tVFS_NodeType        gExt2_DirType;
 \r
 // === PROTOTYPES ===\r
  int   Ext2_Install(char **Arguments);\r
-// Interface Functions\r
+ int   Ext2_Cleanup(void);\r
+// - Interface Functions\r
+ int    Ext2_Detect(int FD);\r
 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
-// Internal Helpers\r
- int           Ext2_int_GetInode(tVFS_Node *Node, 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_UpdateSuperblock(tExt2_Disk *Disk);\r
+void   Ext2_Unmount(tVFS_Node *Node);\r
+void   Ext2_CloseFile(tVFS_Node *Node);\r
+// - Internal Helpers\r
+ int   Ext2_int_GetInode(tVFS_Node *Node, 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
+void   Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);\r
 \r
 // === SEMI-GLOBALS ===\r
-MODULE_DEFINE(0, 0x5B /*v0.90*/, FS_Ext2, Ext2_Install, NULL);\r
+MODULE_DEFINE(0, VERSION, FS_Ext2, Ext2_Install, Ext2_Cleanup);\r
 tExt2_Disk     gExt2_disks[6];\r
  int   giExt2_count = 0;\r
 tVFS_Driver    gExt2_FSInfo = {\r
-       "ext2", 0, Ext2_InitDevice, Ext2_Unmount, NULL\r
+       .Name = "ext2",\r
+       .Detect = Ext2_Detect,\r
+       .InitDevice = Ext2_InitDevice,\r
+       .Unmount = Ext2_Unmount,\r
+       .GetNodeFromINode = NULL\r
        };\r
 \r
 // === CODE ===\r
@@ -46,6 +51,39 @@ int Ext2_Install(char **Arguments)
        return MODULE_ERR_OK;\r
 }\r
 \r
+/**\r
+ * \brief Clean up driver state before unload\r
+ */\r
+int Ext2_Cleanup(void)\r
+{\r
+       return 0;\r
+}\r
+\r
+/**\r
+ * Detect if a volume is Ext2 formatted\r
+ */\r
+int Ext2_Detect(int FD)\r
+{\r
+       tExt2_SuperBlock        sb;\r
+       size_t  len;\r
+       \r
+       len = VFS_ReadAt(FD, 1024, 1024, &sb);\r
+\r
+       if( len != 1024 ) {\r
+               Log_Debug("Ext2", "_Detect: Read failed? (0x%x != 1024)", len);\r
+               return 0;\r
+       }\r
+       \r
+       switch(sb.s_magic)\r
+       {\r
+       case 0xEF53:\r
+               return 2;\r
+       default:\r
+               Log_Debug("Ext2", "_Detect: s_magic = 0x%x", sb.s_magic);\r
+               return 0;\r
+       }\r
+}\r
+\r
 /**\r
  \brief Initializes a device to be read by by the driver\r
  \param Device String - Device to read from\r
@@ -102,10 +140,11 @@ tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)
        disk->CacheID = Inode_GetHandle();\r
        \r
        // Get Block Size\r
-       LOG("s_log_block_size = 0x%x", sb.s_log_block_size);\r
        disk->BlockSize = 1024 << sb.s_log_block_size;\r
+       LOG("Disk->BlockSie = 0x%x (1024 << %i)", disk->BlockSize, sb.s_log_block_size);\r
        \r
        // Read Group Information\r
+       LOG("sb,s_first_data_block = %x", sb.s_first_data_block);\r
        VFS_ReadAt(\r
                disk->FD,\r
                sb.s_first_data_block * disk->BlockSize + 1024,\r
@@ -113,7 +152,6 @@ tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)
                disk->Groups\r
                );\r
        \r
-       #if VERBOSE\r
        LOG("Block Group 0");\r
        LOG(".bg_block_bitmap = 0x%x", disk->Groups[0].bg_block_bitmap);\r
        LOG(".bg_inode_bitmap = 0x%x", disk->Groups[0].bg_inode_bitmap);\r
@@ -122,7 +160,6 @@ tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)
        LOG(".bg_block_bitmap = 0x%x", disk->Groups[1].bg_block_bitmap);\r
        LOG(".bg_inode_bitmap = 0x%x", disk->Groups[1].bg_inode_bitmap);\r
        LOG(".bg_inode_table = 0x%x", disk->Groups[1].bg_inode_table);\r
-       #endif\r
        \r
        // Get root Inode\r
        Ext2_int_ReadInode(disk, 2, &inode);\r
@@ -172,7 +209,40 @@ void Ext2_Unmount(tVFS_Node *Node)
 void Ext2_CloseFile(tVFS_Node *Node)\r
 {\r
        tExt2_Disk      *disk = Node->ImplPtr;\r
-       Inode_UncacheNode(disk->CacheID, Node->Inode);\r
+       ENTER("pNode", Node);\r
+\r
+       if( Mutex_Acquire(&Node->Lock) != 0 )\r
+       {\r
+               LEAVE('-');\r
+               return ;\r
+       }\r
+\r
+       if( Node->Flags & VFS_FFLAG_DIRTY )\r
+       {\r
+               // Commit changes\r
+               Log_Warning("Ext2", "TODO: Commit node changes");\r
+       }\r
+\r
+       int was_not_referenced = (Node->ImplInt == 0);\r
+       tVFS_ACL        *acls = Node->ACLs;\r
+       if( Inode_UncacheNode(disk->CacheID, Node->Inode) == 1 )\r
+       {\r
+               if( was_not_referenced )\r
+               {\r
+                       LOG("Removng inode");\r
+                       // Remove inode\r
+                       Log_Warning("Ext2", "TODO: Remove inode when not deleted");\r
+               }\r
+               if( acls != &gVFS_ACL_EveryoneRW ) {\r
+                       free(acls);\r
+               }\r
+               LOG("Node cleaned");\r
+       }\r
+       else {\r
+               LOG("Still referenced, releasing lock");\r
+               Mutex_Release(&Node->Lock);\r
+       }\r
+       LEAVE('-');\r
        return ;\r
 }\r
 \r
@@ -301,6 +371,14 @@ Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)
        return 0;\r
 }\r
 \r
+/**\r
+ * \brief Reduce the reference count on an inode\r
+ */\r
+void Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode)\r
+{\r
+       \r
+}\r
+\r
 /**\r
  * \fn void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
  * \brief Updates the superblock\r

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