Various Changes
[tpg/acess2.git] / Kernel / vfs / fs / ext2.c
index fe0f25d..50be904 100644 (file)
@@ -13,6 +13,8 @@
 #include <modules.h>\r
 #include "fs_ext2.h"\r
 \r
+#define EXT2_UPDATE_WRITEBACK  1\r
+\r
 // === STRUCTURES ===\r
 typedef struct {\r
         int    FD;\r
@@ -42,6 +44,9 @@ tVFS_Node     *Ext2_FindDir(tVFS_Node *Node, char *FileName);
 tVFS_Node      *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeId, char *Name);\r
  int           Ext2_int_ReadInode(tExt2_Disk *Disk, Uint 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
+Uint32         Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock);\r
+void           Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);\r
 \r
 // === SEMI-GLOBALS ===\r
 MODULE_DEFINE(0, 0x5B /*v0.90*/, EXT2, Ext2_Install, NULL);\r
@@ -478,7 +483,6 @@ int Ext2_MkNod(tVFS_Node *Parent, char *Name, Uint Flags)
 \r
 \r
 /**\r
- \internal\r
  \fn int Ext2_int_GetInode(vfs_node *Node, tExt2_Inode *Inode)\r
  \brief Gets the inode descriptor for a node\r
  \param node   node to get the Inode of\r
@@ -630,3 +634,105 @@ Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)
        free(iBlocks);\r
        return (Uint64)BlockNum * Disk->BlockSize;\r
 }\r
+\r
+/**\r
+ * \fn Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)\r
+ * \brief Allocate an inode (from the current group preferably)\r
+ * \param Disk EXT2 Disk Information Structure\r
+ * \param Parent       Inode ID of the parent (used to locate the child nearby)\r
+ */\r
+Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)\r
+{\r
+//     Uint    block = (Parent - 1) / Disk->SuperBlock.s_inodes_per_group;\r
+       return 0;\r
+}\r
+\r
+/**\r
+ * \fn Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock)\r
+ * \brief Allocate a block from the best possible location\r
+ * \param Disk EXT2 Disk Information Structure\r
+ * \param PrevBlock    Previous block ID in the file\r
+ */\r
+Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock)\r
+{\r
+        int    bpg = Disk->SuperBlock.s_blocks_per_group;\r
+       Uint    blockgroup = PrevBlock / bpg;\r
+       Uint    bitmap[Disk->BlockSize/sizeof(Uint)];\r
+       Uint    bitsperblock = 8*Disk->BlockSize;\r
+        int    i, j = 0;\r
+       Uint    block;\r
+       \r
+       // Are there any free blocks?\r
+       if(Disk->SuperBlock.s_free_blocks_count == 0)   return 0;\r
+       \r
+       if(Disk->Groups[blockgroup].bg_free_blocks_count > 0)\r
+       {\r
+               // Search block group's bitmap\r
+               for(i = 0; i < bpg; i++)\r
+               {\r
+                       // Get the block in the bitmap block\r
+                       j = i & (bitsperblock-1);\r
+                       \r
+                       // Read in if needed\r
+                       if(j == 0) {\r
+                               VFS_ReadAt(\r
+                                       Disk->FD,\r
+                                       (Uint64)Disk->Groups[blockgroup].bg_block_bitmap + i / bitsperblock,\r
+                                       Disk->BlockSize,\r
+                                       bitmap\r
+                                       );\r
+                       }\r
+                       \r
+                       // Fast Check\r
+                       if( bitmap[j/32] == -1 ) {\r
+                               j = (j + 31) & ~31;\r
+                               continue;\r
+                       }\r
+                       \r
+                       // Is the bit set?\r
+                       if( bitmap[j/32] & (1 << (j%32)) )\r
+                               continue;\r
+                       \r
+                       // Ooh! We found one\r
+                       break;\r
+               }\r
+               if( i < bpg ) {\r
+                       Warning("[EXT2 ] Inconsistency detected, Group Free Block count is non-zero when no free blocks exist");\r
+                       goto    checkAll;       // Search the entire filesystem for a free block\r
+                       // Goto needed for neatness\r
+               }\r
+               \r
+               // Mark as used\r
+               bitmap[j/32] |= (1 << (j%32));\r
+               VFS_WriteAt(\r
+                       Disk->FD,\r
+                       (Uint64)Disk->Groups[blockgroup].bg_block_bitmap + i / bitsperblock,\r
+                       Disk->BlockSize,\r
+                       bitmap\r
+                       );\r
+               block = i;\r
+               Disk->Groups[blockgroup].bg_free_blocks_count --;\r
+       }\r
+       else\r
+       {\r
+       checkAll:\r
+               Warning("[EXT2 ] TODO - Implement using blocks outside the current block group");\r
+               return 0;\r
+       }\r
+       \r
+       // Reduce global count\r
+       Disk->SuperBlock.s_free_blocks_count --;\r
+       #if EXT2_UPDATE_WRITEBACK\r
+       Ext2_int_UpdateSuperblock(Disk);\r
+       #endif\r
+       \r
+       return block;\r
+}\r
+\r
+/**\r
+ * \fn void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
+ */\r
+void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
+{\r
+       VFS_WriteAt(Disk->FD, 1024, 1024, &Disk->SuperBlock);\r
+}\r

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