From 1d65dd9606edfcaeef8dfff3724ef6c49180b131 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 17 Feb 2012 22:14:52 +0800 Subject: [PATCH] Modules - Working on LVM layer (not integrated yet) --- KernelLand/Kernel/drvutil.c | 8 +- KernelLand/Kernel/include/api_drv_disk.h | 8 +- KernelLand/Modules/Storage/ATA/main.c | 20 ++- KernelLand/Modules/Storage/LVM/Makefile | 2 +- KernelLand/Modules/Storage/LVM/lvm.h | 24 ++++ KernelLand/Modules/Storage/LVM/lvm_int.h | 39 ++++++ KernelLand/Modules/Storage/LVM/main.c | 166 +++++++++++++++++++++++ KernelLand/Modules/Storage/LVM/mbr.c | 142 +++++++++++-------- KernelLand/Modules/Storage/LVM/mbr.h | 27 ++++ KernelLand/Modules/Storage/LVM/volumes.c | 94 +++++++++++++ Makefile.cfg | 1 + 11 files changed, 456 insertions(+), 75 deletions(-) create mode 100644 KernelLand/Modules/Storage/LVM/mbr.h diff --git a/KernelLand/Kernel/drvutil.c b/KernelLand/Kernel/drvutil.c index d19a0504..d9bd92df 100644 --- a/KernelLand/Kernel/drvutil.c +++ b/KernelLand/Kernel/drvutil.c @@ -556,7 +556,7 @@ void DrvUtil_Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uin // --- Disk Driver Helpers --- Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer, - tDrvUtil_Read_Callback ReadBlocks, Uint64 BlockSize, Uint Argument) + tDrvUtil_Read_Callback ReadBlocks, Uint64 BlockSize, void *Argument) { Uint8 tmp[BlockSize]; // C99 Uint64 block = Start / BlockSize; @@ -566,7 +566,7 @@ Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer, int tailings; Uint64 ret; - ENTER("XStart XLength pBuffer pReadBlocks XBlockSize xArgument", + ENTER("XStart XLength pBuffer pReadBlocks XBlockSize pArgument", Start, Length, Buffer, ReadBlocks, BlockSize, Argument); // Non aligned start, let's fix that! @@ -627,7 +627,7 @@ Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer, Uint64 DrvUtil_WriteBlock(Uint64 Start, Uint64 Length, const void *Buffer, tDrvUtil_Read_Callback ReadBlocks, tDrvUtil_Write_Callback WriteBlocks, - Uint64 BlockSize, Uint Argument) + Uint64 BlockSize, void *Argument) { Uint8 tmp[BlockSize]; // C99 Uint64 block = Start / BlockSize; @@ -637,7 +637,7 @@ Uint64 DrvUtil_WriteBlock(Uint64 Start, Uint64 Length, const void *Buffer, int tailings; Uint64 ret; - ENTER("XStart XLength pBuffer pReadBlocks pWriteBlocks XBlockSize xArgument", + ENTER("XStart XLength pBuffer pReadBlocks pWriteBlocks XBlockSize pArgument", Start, Length, Buffer, ReadBlocks, WriteBlocks, BlockSize, Argument); // Non aligned start, let's fix that! diff --git a/KernelLand/Kernel/include/api_drv_disk.h b/KernelLand/Kernel/include/api_drv_disk.h index 94ea2c94..c37dfec6 100644 --- a/KernelLand/Kernel/include/api_drv_disk.h +++ b/KernelLand/Kernel/include/api_drv_disk.h @@ -148,8 +148,8 @@ enum eTplDisk_CacheFlags * \param Buffer Destination for read blocks * \param Argument Argument provided in ::DrvUtil_ReadBlock and ::DrvUtil_WriteBlock */ -typedef Uint (*tDrvUtil_Read_Callback)(Uint64 Address, Uint Count, void *Buffer, Uint Argument); -typedef Uint (*tDrvUtil_Write_Callback)(Uint64 Address, Uint Count, const void *Buffer, Uint Argument); +typedef Uint (*tDrvUtil_Read_Callback)(Uint64 Address, Uint Count, void *Buffer, void *Argument); +typedef Uint (*tDrvUtil_Write_Callback)(Uint64 Address, Uint Count, const void *Buffer, void *Argument); /** * \brief Reads a range from a block device using aligned reads @@ -162,7 +162,7 @@ typedef Uint (*tDrvUtil_Write_Callback)(Uint64 Address, Uint Count, const void * * \return Number of bytes read */ extern Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer, - tDrvUtil_Read_Callback ReadBlocks, Uint64 BlockSize, Uint Argument); + tDrvUtil_Read_Callback ReadBlocks, Uint64 BlockSize, void *Argument); /** * \brief Writes a range to a block device using aligned writes * \param Start Base byte offset @@ -176,7 +176,7 @@ extern Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer, */ extern Uint64 DrvUtil_WriteBlock(Uint64 Start, Uint64 Length, const void *Buffer, tDrvUtil_Read_Callback ReadBlocks, tDrvUtil_Write_Callback WriteBlocks, - Uint64 BlockSize, Uint Argument); + Uint64 BlockSize, void *Argument); /** * \} diff --git a/KernelLand/Modules/Storage/ATA/main.c b/KernelLand/Modules/Storage/ATA/main.c index 0f344a40..a067430a 100644 --- a/KernelLand/Modules/Storage/ATA/main.c +++ b/KernelLand/Modules/Storage/ATA/main.c @@ -30,8 +30,8 @@ size_t ATA_ReadFS(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer); size_t ATA_WriteFS(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer); int ATA_IOCtl(tVFS_Node *Node, int Id, void *Data); // Read/Write Interface/Quantiser -Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk); -Uint ATA_WriteRaw(Uint64 Address, Uint Count, const void *Buffer, Uint Disk); +Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, void *Argument); +Uint ATA_WriteRaw(Uint64 Address, Uint Count, const void *Buffer, void *Argument); // === GLOBALS === MODULE_DEFINE(0, VERSION, i386ATA, ATA_Install, NULL, "PCI", NULL); @@ -326,7 +326,10 @@ size_t ATA_ReadFS(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer) } { - int ret = DrvUtil_ReadBlock(Offset, Length, Buffer, ATA_ReadRaw, SECTOR_SIZE, disk); + int ret = DrvUtil_ReadBlock( + Offset, Length, Buffer, + ATA_ReadRaw, SECTOR_SIZE, (void*)disk + ); //Log("ATA_ReadFS: disk=%i, Offset=%lli, Length=%lli", disk, Offset, Length); //Debug_HexDump("ATA_ReadFS", Buffer, Length); LEAVE('i', ret); @@ -362,7 +365,10 @@ size_t ATA_WriteFS(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buf Log("ATA_WriteFS: (Node=%p, Offset=0x%llx, Length=0x%llx, Buffer=%p)", Node, Offset, Length, Buffer); Debug_HexDump("ATA_WriteFS", Buffer, Length); - return DrvUtil_WriteBlock(Offset, Length, Buffer, ATA_ReadRaw, ATA_WriteRaw, SECTOR_SIZE, disk); + return DrvUtil_WriteBlock( + Offset, Length, Buffer, + ATA_ReadRaw, ATA_WriteRaw, SECTOR_SIZE, (void*)disk + ); } const char *csaATA_IOCtls[] = {DRV_IOCTLNAMES, DRV_DISK_IOCTLNAMES, NULL}; @@ -389,8 +395,9 @@ int ATA_IOCtl(tVFS_Node *UNUSED(Node), int Id, void *Data) /** * \fn Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk) */ -Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk) +Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, void *Argument) { + int Disk = (tVAddr)Argument; int ret; Uint offset; Uint done = 0; @@ -424,8 +431,9 @@ Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk) /** * \fn Uint ATA_WriteRaw(Uint64 Address, Uint Count, const void *Buffer, Uint Disk) */ -Uint ATA_WriteRaw(Uint64 Address, Uint Count, const void *Buffer, Uint Disk) +Uint ATA_WriteRaw(Uint64 Address, Uint Count, const void *Buffer, void *Argument) { + int Disk = (tVAddr)Argument; int ret; Uint offset; Uint done = 0; diff --git a/KernelLand/Modules/Storage/LVM/Makefile b/KernelLand/Modules/Storage/LVM/Makefile index 1f871124..20591de6 100644 --- a/KernelLand/Modules/Storage/LVM/Makefile +++ b/KernelLand/Modules/Storage/LVM/Makefile @@ -3,7 +3,7 @@ # - Handles MBR Partitions (and eventually others) # -OBJ = main.o mbr.o +OBJ = main.o volumes.o mbr.o NAME = LVM -include ../Makefile.tpl diff --git a/KernelLand/Modules/Storage/LVM/lvm.h b/KernelLand/Modules/Storage/LVM/lvm.h index e69de29b..0d0a2529 100644 --- a/KernelLand/Modules/Storage/LVM/lvm.h +++ b/KernelLand/Modules/Storage/LVM/lvm.h @@ -0,0 +1,24 @@ +/* + * Acess2 Logical Volume Manager + * - By John Hodge (thePowersGang) + * + * lvm.h + * - LVM Core definitions + */ +#ifndef _LVM_LVM_H_ +#define _LVM_LVM_H_ + +#include + +// === TYPES === +typedef struct sLVM_Vol tLVM_Vol; + +// === FUNCTIONS === +extern size_t LVM_int_ReadVolume(tLVM_Vol *Volume, Uint64 BlockNum, size_t BlockCount, void *Dest); +extern size_t LVM_int_WriteVolume(tLVM_Vol *Volume, Uint64 BlockNum, size_t BlockCount, const void *Src); + +// --- Subvolume Management --- +extern void LVM_int_SetSubvolume_Anon(tLVM_Vol *Volume, int Index, Uint64 FirstBlock, Uint64 LastBlock); + +#endif + diff --git a/KernelLand/Modules/Storage/LVM/lvm_int.h b/KernelLand/Modules/Storage/LVM/lvm_int.h index 36f2eb2c..7f528d90 100644 --- a/KernelLand/Modules/Storage/LVM/lvm_int.h +++ b/KernelLand/Modules/Storage/LVM/lvm_int.h @@ -5,4 +5,43 @@ * lvm_int.h * - Internal definitions */ +#ifndef _LVM_LVM_INT_H_ +#define _LVM_LVM_INT_H_ + +#include "lvm.h" +#include + +typedef struct sLVM_SubVolume tLVM_SubVolume; + +struct sLVM_Vol +{ + tLVM_Vol *Next; + + tVFS_Node Node; + + int BackingDescriptor; + size_t BlockSize; + + int nSubVolumes; + tLVM_SubVolume **SubVolumes; + + char Name[]; +}; + +struct sLVM_SubVolume +{ + tLVM_Vol *Vol; + + tVFS_Node Node; + + // Note: Only for a simple volume + Uint64 FirstBlock; + Uint64 BlockCount; + + char Name[]; +}; + +extern tVFS_NodeType gLVM_SubVolNodeType; + +#endif diff --git a/KernelLand/Modules/Storage/LVM/main.c b/KernelLand/Modules/Storage/LVM/main.c index e69de29b..587689ef 100644 --- a/KernelLand/Modules/Storage/LVM/main.c +++ b/KernelLand/Modules/Storage/LVM/main.c @@ -0,0 +1,166 @@ +/* + * Acess2 Logical Volume Manager + * - By John Hodge (thePowersGang) + * + * lvm.h + * - LVM Core definitions + */ +#define DEBUG 0 +#define VERSION VER2(0,1) +#include "lvm_int.h" +#include +#include +#include + +// === PROTOTYPES === +// --- + int LVM_Initialise(char **Arguments); +void LVM_Cleanup(void); +// --- +char *LVM_Root_ReadDir(tVFS_Node *Node, int ID); +tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name); +char *LVM_Vol_ReadDir(tVFS_Node *Node, int ID); +tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name); +size_t LVM_SubVol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer); +size_t LVM_SubVol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer); + +Uint LVM_int_DrvUtil_ReadBlock(Uint64 Address, Uint Count, void *Buffer, void *Argument); +Uint LVM_int_DrvUtil_WriteBlock(Uint64 Address, Uint Count, const void *Buffer, void *Argument); + +// === GLOBALS === +MODULE_DEFINE(0, VERSION, LVM, LVM_Initialise, LVM_Cleanup, NULL); +tVFS_NodeType gLVM_RootNodeType = { + .ReadDir = LVM_Root_ReadDir, + .FindDir = LVM_Root_FindDir +}; +tVFS_NodeType gLVM_VolNodeType = { + .ReadDir = LVM_Vol_ReadDir, + .FindDir = LVM_Vol_FindDir +}; +tVFS_NodeType gLVM_SubVolNodeType = { + .Read = LVM_SubVol_Read, + .Write = LVM_SubVol_Write +}; +tDevFS_Driver gLVM_DevFS = { + NULL, "LVM", + {.Flags = VFS_FFLAG_DIRECTORY, .Type = &gLVM_RootNodeType} +}; + +tLVM_Vol *gpLVM_FirstVolume; +tLVM_Vol *gpLVM_LastVolume = (void*)&gpLVM_FirstVolume; + +// === CODE === +int LVM_Initialise(char **Arguments) +{ + DevFS_AddDevice( &gLVM_DevFS ); + return 0; +} + +void LVM_Cleanup(void) +{ + +} + +// -------------------------------------------------------------------- +// VFS Inteface +// -------------------------------------------------------------------- +char *LVM_Root_ReadDir(tVFS_Node *Node, int ID) +{ + tLVM_Vol *vol; + + if( ID < 0 ) return NULL; + + for( vol = gpLVM_FirstVolume; vol && ID --; vol = vol->Next ); + + if(vol) + return strdup(vol->Name); + else + return NULL; +} +tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name) +{ + tLVM_Vol *vol; + for( vol = gpLVM_FirstVolume; vol; vol = vol->Next ) + { + if( strcmp(vol->Name, Name) == 0 ) + { + return &vol->Node; + } + } + return NULL; +} + +char *LVM_Vol_ReadDir(tVFS_Node *Node, int ID) +{ + tLVM_Vol *vol = Node->ImplPtr; + + if( ID < 0 || ID >= vol->nSubVolumes ) + return NULL; + + return strdup( vol->SubVolumes[ID]->Name ); +} +tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name) +{ + tLVM_Vol *vol = Node->ImplPtr; + + for( int i = 0; i < vol->nSubVolumes; i ++ ) + { + if( strcmp(vol->SubVolumes[i]->Name, Name) == 0 ) + { + return &vol->SubVolumes[i]->Node; + } + } + + return NULL; +} + +size_t LVM_SubVol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer) +{ + tLVM_SubVolume *sv = Node->ImplPtr; + Uint64 byte_size = sv->BlockCount * sv->Vol->BlockSize; + + if( Offset > byte_size ) + return 0; + if( Length > byte_size ) + Length = byte_size; + if( Offset + Length > byte_size ) + Length = byte_size - Offset; + + Offset += sv->FirstBlock * sv->Vol->BlockSize; + + return DrvUtil_ReadBlock( + Offset, Length, Buffer, + LVM_int_DrvUtil_ReadBlock, sv->Vol->BlockSize, sv->Vol + ); +} +size_t LVM_SubVol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer) +{ + tLVM_SubVolume *sv = Node->ImplPtr; + Uint64 byte_size = sv->BlockCount * sv->Vol->BlockSize; + + if( Offset > byte_size ) + return 0; + if( Length > byte_size ) + Length = byte_size; + if( Offset + Length > byte_size ) + Length = byte_size - Offset; + + Offset += sv->FirstBlock * sv->Vol->BlockSize; + + return DrvUtil_WriteBlock( + Offset, Length, Buffer, + LVM_int_DrvUtil_ReadBlock, LVM_int_DrvUtil_WriteBlock, + sv->Vol->BlockSize, sv->Vol + ); +} + +Uint LVM_int_DrvUtil_ReadBlock(Uint64 Address, Uint Count, void *Buffer, void *Argument) +{ + return LVM_int_ReadVolume( Argument, Address, Count, Buffer ); +} + +Uint LVM_int_DrvUtil_WriteBlock(Uint64 Address, Uint Count, const void *Buffer, void *Argument) +{ + return LVM_int_WriteVolume( Argument, Address, Count, Buffer ); +} + diff --git a/KernelLand/Modules/Storage/LVM/mbr.c b/KernelLand/Modules/Storage/LVM/mbr.c index 8cbb5b19..169f6f36 100644 --- a/KernelLand/Modules/Storage/LVM/mbr.c +++ b/KernelLand/Modules/Storage/LVM/mbr.c @@ -1,66 +1,93 @@ /* - * Acess2 IDE Harddisk Driver - * - MBR Parsing Code + * Acess2 Logical Volume Manager + * - By John Hodge (thePowersGang) + * * mbr.c + * - MBR Parsing Code */ #define DEBUG 0 #include -#include "lvm_int.h" +#include "lvm.h" +#include "mbr.h" // === PROTOTYPES === -void LVM_MBR_Initialise(int Disk, tMBR *MBR); -Uint64 LVM_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length); + int LVM_MBR_CountSubvolumes(tLVM_Vol *Volume, void *FirstSector); +void LVM_MBR_PopulateSubvolumes(tLVM_Vol *Volume, void *FirstSector); +Uint64 LVM_MBR_int_ReadExt(tLVM_Vol *Volume, Uint64 Addr, Uint64 *Base, Uint64 *Length); // === GLOBALS === // === CODE === /** - * \fn void ATA_ParseMBR(int Disk, tMBR *MBR) + * \brief Initialise a volume as */ -void ATA_ParseMBR(int Disk, tMBR *MBR) +int LVM_MBR_CountSubvolumes(tLVM_Vol *Volume, void *FirstSector) { - int i, j = 0, k = 4; + tMBR *MBR = FirstSector; + int i; Uint64 extendedLBA; Uint64 base, len; + int numPartitions = 0; - ENTER("iDisk", Disk); + ENTER("pVolume pFirstSector", Volume, FirstSector); // Count Partitions - gATA_Disks[Disk].NumPartitions = 0; + numPartitions = 0; extendedLBA = 0; for( i = 0; i < 4; i ++ ) { if( MBR->Parts[i].SystemID == 0 ) continue; - if( MBR->Parts[i].Boot == 0x0 || MBR->Parts[i].Boot == 0x80 // LBA 28 - || MBR->Parts[i].Boot == 0x1 || MBR->Parts[i].Boot == 0x81 // LBA 48 - ) + + if( MBR->Parts[i].Boot == 0x0 || MBR->Parts[i].Boot == 0x80 ) // LBA 28 + { + base = MBR->Parts[i].LBAStart; + } + else if( MBR->Parts[i].Boot == 0x1 || MBR->Parts[i].Boot == 0x81 ) // LBA 48 + { + base = (MBR->Parts[i].StartHi << 16) | MBR->Parts[i].LBAStart; + } + else + continue ; // Invalid, so don't count + + if( MBR->Parts[i].SystemID == 0xF || MBR->Parts[i].SystemID == 5 ) { - if( MBR->Parts[i].SystemID == 0xF || MBR->Parts[i].SystemID == 5 ) { - LOG("Extended Partition at 0x%llx", MBR->Parts[i].LBAStart); - if(extendedLBA != 0) { - Warning("Disk %i has multiple extended partitions, ignoring rest", Disk); - continue; - } - extendedLBA = MBR->Parts[i].LBAStart; + LOG("Extended Partition at 0x%llx", base); + if(extendedLBA != 0) { + Log_Warning( + "LBA MBR", + "Volume %p has multiple extended partitions, ignoring all but first", + Volume + ); continue; } - LOG("Primary Partition at 0x%llx", MBR->Parts[i].LBAStart); - - gATA_Disks[Disk].NumPartitions ++; - continue; + extendedLBA = base; + } + else + { + LOG("Primary Partition at 0x%llx", base); + numPartitions ++; } - // Invalid Partition, so don't count it } while(extendedLBA != 0) { - extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len); + extendedLBA = LVM_MBR_int_ReadExt(Volume, extendedLBA, &base, &len); if( extendedLBA == -1 ) break; - gATA_Disks[Disk].NumPartitions ++; + numPartitions ++; } - LOG("gATA_Disks[Disk].NumPartitions = %i", gATA_Disks[Disk].NumPartitions); - - // Create patition array - gATA_Disks[Disk].Partitions = malloc( gATA_Disks[Disk].NumPartitions * sizeof(tATA_Partition) ); + LOG("numPartitions = %i", numPartitions); + + LEAVE('i', numPartitions); + return numPartitions; +} + +void LVM_MBR_PopulateSubvolumes(tLVM_Vol *Volume, void *FirstSector) +{ + Uint64 extendedLBA; + Uint64 base, len; + int i, j; + tMBR *MBR = FirstSector; + + ENTER("pVolume pFirstSector", Volume, FirstSector); // --- Fill Partition Info --- extendedLBA = 0; @@ -73,7 +100,7 @@ void ATA_ParseMBR(int Disk, tMBR *MBR) base = MBR->Parts[i].LBAStart; len = MBR->Parts[i].LBALength; } - else if( MBR->Parts[i].Boot == 0x1 || MBR->Parts[i].Boot == 0x81 ) // LBA 58 + else if( MBR->Parts[i].Boot == 0x1 || MBR->Parts[i].Boot == 0x81 ) // LBA 48 { base = (MBR->Parts[i].StartHi << 16) | MBR->Parts[i].LBAStart; len = (MBR->Parts[i].LengthHi << 16) | MBR->Parts[i].LBALength; @@ -82,29 +109,22 @@ void ATA_ParseMBR(int Disk, tMBR *MBR) continue; if( MBR->Parts[i].SystemID == 0xF || MBR->Parts[i].SystemID == 5 ) { - if(extendedLBA != 0) { - Log_Warning("ATA", "Disk %i has multiple extended partitions, ignoring rest", Disk); - continue; - } - extendedLBA = base; + if(extendedLBA == 0) + extendedLBA = base; continue; } // Create Partition - ATA_int_MakePartition( - &gATA_Disks[Disk].Partitions[j], Disk, j, - base, len - ); + LVM_int_SetSubvolume_Anon( Volume, j, base, len ); j ++; } // Scan extended partitions while(extendedLBA != 0) { - extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len); + extendedLBA = LVM_MBR_int_ReadExt(Volume, extendedLBA, &base, &len); if(extendedLBA == -1) break; - ATA_int_MakePartition( - &gATA_Disks[Disk].Partitions[j], Disk, k, base, len - ); + LVM_int_SetSubvolume_Anon( Volume, j, base, len ); + j ++ ; } LEAVE('-'); @@ -114,7 +134,7 @@ void ATA_ParseMBR(int Disk, tMBR *MBR) * \brief Reads an extended partition * \return LBA of next Extended, -1 on error, 0 for last */ -Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length) +Uint64 LVM_MBR_int_ReadExt(tLVM_Vol *Volume, Uint64 Addr, Uint64 *Base, Uint64 *Length) { Uint64 link = 0; int bFoundPart = 0;; @@ -122,7 +142,8 @@ Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length) tMBR mbr; Uint64 base, len; - if( ATA_ReadDMA( Disk, Addr, 1, &mbr ) != 0 ) + // TODO: Handle non-512 byte sectors + if( LVM_int_ReadVolume( Volume, Addr, 1, &mbr ) != 0 ) return -1; // Stop on Errors for( i = 0; i < 4; i ++ ) @@ -140,9 +161,9 @@ Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length) len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength; } else { - Log_Warning("ATA MBR", - "Unknown partition type 0x%x, Disk %i Ext 0x%llx Part %i", - mbr.Parts[i].Boot, Disk, Addr, i + Log_Warning("LVM MBR", + "Unknown partition type 0x%x, Volume %p Ext 0x%llx Part %i", + mbr.Parts[i].Boot, Volume, Addr, i ); return -1; } @@ -152,9 +173,9 @@ Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length) case 0xF: case 0x5: if(link != 0) { - Log_Warning("ATA MBR", - "Disk %i has two forward links in the extended partition", - Disk + Log_Warning("LVM MBR", + "Volume %p has two forward links in the extended partition", + Volume ); return -1; } @@ -162,23 +183,24 @@ Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length) break; default: if(bFoundPart) { - Warning("ATA MBR", - "Disk %i has more than one partition in the extended partition at 0x%llx", - Disk, Addr + Warning("LVM MBR", + "Volume %p has more than one partition in the extended partition at 0x%llx", + Volume, Addr ); return -1; } bFoundPart = 1; - *Base = base; + *Base = Addr + base; // Extended partitions are based off the sub-mbr *Length = len; break; } } if(!bFoundPart) { - Log_Warning("ATA MBR", - "No partition in extended partiton, Disk %i 0x%llx", - Disk, Addr); + Log_Warning("LVM MBR", + "No partition in extended partiton, Volume %p 0x%llx", + Volume, Addr + ); return -1; } diff --git a/KernelLand/Modules/Storage/LVM/mbr.h b/KernelLand/Modules/Storage/LVM/mbr.h new file mode 100644 index 00000000..01efd04b --- /dev/null +++ b/KernelLand/Modules/Storage/LVM/mbr.h @@ -0,0 +1,27 @@ +/* + * Acess2 Logical Volume Manager + * - By John Hodge (thePowersGang) + * + * mbr.h + * - MBR Definitions + */ +#ifndef _LVM_MBR_H_ +#define _LVM_MBR_H_ + +typedef struct +{ + Uint8 BootCode[0x1BE]; + struct { + Uint8 Boot; + Uint8 Unused1; // Also CHS Start + Uint16 StartHi; // Also CHS Start + Uint8 SystemID; + Uint8 Unused2; // Also CHS Length + Uint16 LengthHi; // Also CHS Length + Uint32 LBAStart; + Uint32 LBALength; + } __attribute__ ((packed)) Parts[4]; + Uint16 BootFlag; // = 0xAA 55 +} __attribute__ ((packed)) tMBR; + +#endif diff --git a/KernelLand/Modules/Storage/LVM/volumes.c b/KernelLand/Modules/Storage/LVM/volumes.c index e69de29b..aac987e2 100644 --- a/KernelLand/Modules/Storage/LVM/volumes.c +++ b/KernelLand/Modules/Storage/LVM/volumes.c @@ -0,0 +1,94 @@ +/* + * Acess2 Logical Volume Manager + * - By John Hodge (thePowersGang) + * + * volumes.c + * - Volume management + */ +#include "lvm_int.h" + +// === PROTOTYPES === + +// === CODE === +// -------------------------------------------------------------------- +// Managment / Initialisation +// -------------------------------------------------------------------- +int LVM_AddVolume(const char *Name, int FD) +{ + // Make dummy volume descriptor (for the read code) + + // Determine Type + + // Type->CountSubvolumes + + // Create real volume descriptor + + // Type->PopulateSubvolumes + + // Add to volume list + + return 0; +} + +void LVM_int_SetSubvolume_Anon(tLVM_Vol *Volume, int Index, Uint64 FirstBlock, Uint64 BlockCount) +{ + tLVM_SubVolume *sv; + int namelen; + + if( Index < 0 || Index >= Volume->nSubVolumes ) { + Log_Warning("LVM", "SV ID is out of range (0 < %i < %i)", + Index, Volume->nSubVolumes); + return ; + } + + if( Volume->SubVolumes[Index] ) { + Log_Warning("LVM", "Attempt to set SV %i of %p twice", Index, Volume); + return ; + } + + namelen = snprintf(NULL, 0, "%i", Index); + + sv = malloc( sizeof(tLVM_SubVolume) + namelen + 1 ); + if(!sv) { + // Oh, f*ck + return ; + } + Volume->SubVolumes[Index] = sv; + + sv->Vol = Volume; + sprintf(sv->Name, "%i", Index); + sv->FirstBlock = FirstBlock; + sv->BlockCount = BlockCount; + memset(&sv->Node, 0, sizeof(tVFS_Node)); + + sv->Node.ImplPtr = sv; + sv->Node.Type = &gLVM_SubVolNodeType; +} + +// -------------------------------------------------------------------- +// IO +// -------------------------------------------------------------------- +size_t LVM_int_ReadVolume(tLVM_Vol *Volume, Uint64 BlockNum, size_t BlockCount, void *Dest) +{ + size_t rv; + rv = VFS_ReadAt( + Volume->BackingDescriptor, + BlockNum * Volume->BlockSize, + BlockCount * Volume->BlockSize, + Dest + ); + return rv / Volume->BlockSize; +} + +size_t LVM_int_WriteVolume(tLVM_Vol *Volume, Uint64 BlockNum, size_t BlockCount, const void *Src) +{ + size_t rv; + rv = VFS_WriteAt( + Volume->BackingDescriptor, + BlockNum * Volume->BlockSize, + BlockCount * Volume->BlockSize, + Src + ); + return rv / Volume->BlockSize; +} + diff --git a/Makefile.cfg b/Makefile.cfg index d14b29c2..2642f5a5 100644 --- a/Makefile.cfg +++ b/Makefile.cfg @@ -54,6 +54,7 @@ MODULES := MODULES += Filesystems/Ext2 MODULES += Filesystems/FAT MODULES += Filesystems/NTFS +MODULES += Storage/LVM include $(ACESSDIR)/BuildConf/$(ARCH)/$(PLATFORM).mk -- 2.20.1