From cbe0bf8833612d7581e96a55681fc576202d2969 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 27 Jul 2013 23:50:05 +0800 Subject: [PATCH] Modules/Ext2 - Bugfixing to write support --- KernelLand/Modules/Filesystems/Ext2/dir.c | 13 ++++--- KernelLand/Modules/Filesystems/Ext2/ext2.c | 12 +++++-- KernelLand/Modules/Filesystems/Ext2/write.c | 40 +++++++++++++-------- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/KernelLand/Modules/Filesystems/Ext2/dir.c b/KernelLand/Modules/Filesystems/Ext2/dir.c index 2f2b72f6..a0a5f146 100644 --- a/KernelLand/Modules/Filesystems/Ext2/dir.c +++ b/KernelLand/Modules/Filesystems/Ext2/dir.c @@ -237,7 +237,6 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child) Uint64 base; // Block's Base Address int block = 0, ofs = 0; Uint size; - void *blockData; int bestMatch = -1; int bestSize=0, bestBlock=0, bestOfs=0, bestNeedsSplit=0; int nEntries; @@ -245,7 +244,7 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child) ENTER("pNode sName pChild", Node, Name, Child); - blockData = malloc(disk->BlockSize); + void *blockData = malloc(disk->BlockSize); // Read child inode (get's the file type) Ext2_int_ReadInode(disk, Child->Inode, &inode); @@ -306,9 +305,7 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child) LOG(" name='%.*s'", dirent->name_len, dirent->name); if(strncmp(Name, dirent->name, dirent->name_len) == 0) { //Ext2_int_UnlockInode(disk, Node->Inode); - Mutex_Release(&Node->Lock); - LEAVE('i', 1); - return 1; // ERR_??? + goto _err; } int spare_space = dirent->rec_len - (dirent->name_len + EXT2_DIRENT_SIZE); @@ -393,8 +390,14 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child) Child->Flags |= VFS_FFLAG_DIRTY; //Ext2_int_UnlockInode(disk, Node->Inode); + free(blockData); Mutex_Release(&Node->Lock); LEAVE('i', 0); return 0; +_err: + free(blockData); + Mutex_Release(&Node->Lock); + LEAVE('i', 1); + return 1; // ERR_??? } diff --git a/KernelLand/Modules/Filesystems/Ext2/ext2.c b/KernelLand/Modules/Filesystems/Ext2/ext2.c index 516fe0b9..3a9a080e 100644 --- a/KernelLand/Modules/Filesystems/Ext2/ext2.c +++ b/KernelLand/Modules/Filesystems/Ext2/ext2.c @@ -395,7 +395,7 @@ tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID) int Ext2_int_WritebackNode(tExt2_Disk *Disk, tVFS_Node *Node) { - tExt2_Inode inode; + tExt2_Inode inode = {0}; if( Disk != Node->ImplPtr ) { Log_Error("Ext2", "Ext2_int_WritebackNode - Disk != Node->ImplPtr"); @@ -529,7 +529,7 @@ Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent) VFS_ReadAt(Disk->FD, Disk->BlockSize*bg->bg_inode_bitmap+ofs, sector_size, buf); int byte, bit; - for( byte = 0; byte < sector_size && buf[byte] != 0xFF; byte ++ ) + for( byte = 0; byte < sector_size && buf[byte] == 0xFF; byte ++ ) ; if( byte < sector_size ) { @@ -577,6 +577,14 @@ void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk) // Update Primary VFS_WriteAt(Disk->FD, 1024, 1024, &Disk->SuperBlock); + // - Update block groups while we're at it + VFS_WriteAt( + Disk->FD, + Disk->SuperBlock.s_first_data_block * Disk->BlockSize + 1024, + sizeof(tExt2_Group)*Disk->GroupCount, + Disk->Groups + ); + // Secondaries // at Block Group 1, 3^n, 5^n, 7^n diff --git a/KernelLand/Modules/Filesystems/Ext2/write.c b/KernelLand/Modules/Filesystems/Ext2/write.c index 207bf87b..022bc96a 100644 --- a/KernelLand/Modules/Filesystems/Ext2/write.c +++ b/KernelLand/Modules/Filesystems/Ext2/write.c @@ -30,7 +30,7 @@ size_t Ext2_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buff Uint64 allocSize; int bNewBlocks = 0; - Debug_HexDump("Ext2_Write", Buffer, Length); + //Debug_HexDump("Ext2_Write", Buffer, Length); // TODO: Handle (Flags & VFS_IOFLAG_NOBLOCK) @@ -157,24 +157,30 @@ Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock) if(Disk->SuperBlock.s_free_blocks_count == 0) return 0; - // First: Check the next block after \a PrevBlock - if( (PrevBlock + 1) % Disk->SuperBlock.s_blocks_per_group != 0 - && Disk->Groups[blockgroup].bg_free_blocks_count > 0 ) + // First: Check the next block after `PrevBlock` + int iblock = (PrevBlock + 1) % Disk->SuperBlock.s_blocks_per_group; + if( iblock != 0 && Disk->Groups[blockgroup].bg_free_blocks_count > 0 ) { + LOG("Checking %i:%i", blockgroup, iblock); + bg = &Disk->Groups[blockgroup]; + const int sector_size = 512; Uint8 buf[sector_size]; - int iblock = (PrevBlock + 1) % Disk->SuperBlock.s_blocks_per_group; - int byte = iblock / 8; - int ofs = byte / sector_size * sector_size; + int byte = (iblock/8) % sector_size; + Uint8 bit = 1 << (iblock % 8); + int ofs = (iblock/8) / sector_size * sector_size; byte %= sector_size; - VFS_ReadAt(Disk->FD, Disk->BlockSize*bg->bg_block_bitmap+ofs, sector_size, buf); - - if( (buf[byte] & (1 << (iblock%8))) == 0 ) + Uint64 vol_ofs = Disk->BlockSize*bg->bg_block_bitmap+ofs; + VFS_ReadAt(Disk->FD, vol_ofs, sector_size, buf); + + LOG("buf@%llx[%i] = %02x (& %02x)", vol_ofs, byte, buf[byte], bit); + + if( (buf[byte] & bit) == 0 ) { // Free block - nice and contig allocation - buf[byte] |= (1 << (iblock%8)); - VFS_WriteAt(Disk->FD, Disk->BlockSize*bg->bg_block_bitmap+ofs, sector_size, buf); + buf[byte] |= bit; + VFS_WriteAt(Disk->FD, vol_ofs, sector_size, buf); bg->bg_free_blocks_count --; Disk->SuperBlock.s_free_blocks_count --; @@ -192,6 +198,7 @@ Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock) blockgroup ++; if( Disk->Groups[blockgroup].bg_free_blocks_count == 0 ) { + LOG("Roll over"); blockgroup = 0; while( blockgroup < firstgroup && Disk->Groups[blockgroup].bg_free_blocks_count == 0 ) blockgroup ++; @@ -201,6 +208,7 @@ Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock) Disk); return 0; } + LOG("BG%i has free blocks", blockgroup); // Search the bitmap for a free block bg = &Disk->Groups[blockgroup]; @@ -208,18 +216,20 @@ Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock) do { const int sector_size = 512; Uint8 buf[sector_size]; - VFS_ReadAt(Disk->FD, Disk->BlockSize*bg->bg_block_bitmap+ofs, sector_size, buf); + Uint64 vol_ofs = Disk->BlockSize*bg->bg_block_bitmap+ofs; + VFS_ReadAt(Disk->FD, vol_ofs, sector_size, buf); int byte, bit; - for( byte = 0; byte < sector_size && buf[byte] != 0xFF; byte ++ ) + for( byte = 0; byte < sector_size && buf[byte] == 0xFF; byte ++ ) ; if( byte < sector_size ) { + LOG("buf@%llx[%i] = %02x", vol_ofs, byte, buf[byte]); for( bit = 0; bit < 8 && buf[byte] & (1 << bit); bit ++) ; ASSERT(bit != 8); buf[byte] |= 1 << bit; - VFS_WriteAt(Disk->FD, Disk->BlockSize*bg->bg_block_bitmap+ofs, sector_size, buf); + VFS_WriteAt(Disk->FD, vol_ofs, sector_size, buf); bg->bg_free_blocks_count --; Disk->SuperBlock.s_free_blocks_count --; -- 2.20.1