From 06674bf290ab6a24398a5fde1b67060673e267ad Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 19 May 2012 19:39:39 +0800 Subject: [PATCH] Modules/{ATA,LVM} - Moved ATA to use the LVM partition code --- KernelLand/Modules/Storage/ATA/Makefile | 2 +- KernelLand/Modules/Storage/ATA/common.h | 4 - KernelLand/Modules/Storage/ATA/main.c | 329 ++----------------- KernelLand/Modules/Storage/ATA/mbr.c | 193 ----------- KernelLand/Modules/Storage/LVM/include/lvm.h | 16 +- KernelLand/Modules/Storage/LVM/lvm_int.h | 4 +- KernelLand/Modules/Storage/LVM/main.c | 23 +- KernelLand/Modules/Storage/LVM/volumes.c | 46 +-- 8 files changed, 86 insertions(+), 531 deletions(-) delete mode 100644 KernelLand/Modules/Storage/ATA/mbr.c diff --git a/KernelLand/Modules/Storage/ATA/Makefile b/KernelLand/Modules/Storage/ATA/Makefile index 22923422..5e62dd02 100644 --- a/KernelLand/Modules/Storage/ATA/Makefile +++ b/KernelLand/Modules/Storage/ATA/Makefile @@ -1,7 +1,7 @@ # # -OBJ = main.o io.o mbr.o +OBJ = main.o io.o NAME = ATA -include ../Makefile.tpl diff --git a/KernelLand/Modules/Storage/ATA/common.h b/KernelLand/Modules/Storage/ATA/common.h index 891d2bbe..1ca3a994 100644 --- a/KernelLand/Modules/Storage/ATA/common.h +++ b/KernelLand/Modules/Storage/ATA/common.h @@ -43,10 +43,6 @@ typedef struct typedef struct { Uint64 Sectors; - char Name[2]; - tVFS_Node Node; - int NumPartitions; - tATA_Partition *Partitions; } tATA_Disk; // === GLOBALS === diff --git a/KernelLand/Modules/Storage/ATA/main.c b/KernelLand/Modules/Storage/ATA/main.c index cc1fe62a..6737e447 100644 --- a/KernelLand/Modules/Storage/ATA/main.c +++ b/KernelLand/Modules/Storage/ATA/main.c @@ -11,6 +11,7 @@ #include #include #include "common.h" +#include // === MACROS === #define IO_DELAY() do{inb(0x80); inb(0x80); inb(0x80); inb(0x80);}while(0) @@ -18,47 +19,22 @@ // === PROTOTYPES === int ATA_Install(char **Arguments); void ATA_SetupPartitions(void); -void ATA_SetupVFS(void); int ATA_ScanDisk(int Disk); void ATA_ParseGPT(int Disk); void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length); Uint16 ATA_GetBasePort(int Disk); -// Filesystem Interface -char *ATA_ReadDir(tVFS_Node *Node, int Pos); -tVFS_Node *ATA_FindDir(tVFS_Node *Node, const char *Name); -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, void *Argument); -Uint ATA_WriteRaw(Uint64 Address, Uint Count, const void *Buffer, void *Argument); +int ATA_ReadRaw(void *Ptr, Uint64 Address, size_t Count, void *Buffer); +int ATA_WriteRaw(void *Ptr, Uint64 Address, size_t Count, const void *Buffer); // === GLOBALS === -MODULE_DEFINE(0, VERSION, i386ATA, ATA_Install, NULL, "PCI", NULL); -tVFS_NodeType gATA_RootNodeType = { - .TypeName = "ATA Root Node", - .ReadDir = ATA_ReadDir, - .FindDir = ATA_FindDir +MODULE_DEFINE(0, VERSION, i386ATA, ATA_Install, NULL, "PCI", "LVM", NULL); +tLVM_VolType gATA_VolType = { + .Name = "ATA", + .Read = ATA_ReadRaw, + .Write = ATA_WriteRaw, + .BlockSize = 512, }; -tVFS_NodeType gATA_DiskNodeType = { - .TypeName = "ATA Volume", - .Read = ATA_ReadFS, - .Write = ATA_WriteFS, - .IOCtl = ATA_IOCtl - }; -tDevFS_Driver gATA_DriverInfo = { - NULL, "ata", - { - .NumACLs = 1, - .Size = -1, - .Flags = VFS_FFLAG_DIRECTORY, - .ACLs = &gVFS_ACL_EveryoneRX, - .Type = &gATA_RootNodeType - } -}; -tATA_Disk gATA_Disks[MAX_ATA_DISKS]; - int giATA_NumNodes; -tVFS_Node **gATA_Nodes; // === CODE === /** @@ -73,11 +49,6 @@ int ATA_Install(char **Arguments) ATA_SetupPartitions(); - ATA_SetupVFS(); - - if( DevFS_AddDevice( &gATA_DriverInfo ) == 0 ) - return MODULE_ERR_MISC; - return MODULE_ERR_OK; } @@ -90,72 +61,31 @@ void ATA_SetupPartitions(void) for( i = 0; i < MAX_ATA_DISKS; i ++ ) { if( !ATA_ScanDisk(i) ) { - gATA_Disks[i].Name[0] = '\0'; // Mark as unused continue; } } } -/** - * \brief Sets up the ATA drivers VFS information and registers with DevFS - */ -void ATA_SetupVFS(void) -{ - int i, j, k; - - // Count number of nodes needed - giATA_NumNodes = 0; - for( i = 0; i < MAX_ATA_DISKS; i++ ) - { - if(gATA_Disks[i].Name[0] == '\0') continue; // Ignore - giATA_NumNodes ++; - giATA_NumNodes += gATA_Disks[i].NumPartitions; - } - - // Allocate Node space - gATA_Nodes = malloc( giATA_NumNodes * sizeof(void*) ); - - // Set nodes - k = 0; - for( i = 0; i < MAX_ATA_DISKS; i++ ) - { - if(gATA_Disks[i].Name[0] == '\0') continue; // Ignore - gATA_Nodes[ k++ ] = &gATA_Disks[i].Node; - for( j = 0; j < gATA_Disks[i].NumPartitions; j ++ ) - gATA_Nodes[ k++ ] = &gATA_Disks[i].Partitions[j].Node; - } - - gATA_DriverInfo.RootNode.Size = giATA_NumNodes; -} - /** * \brief Scan a disk, getting the size and any paritions * \param Disk Disk ID to scan */ int ATA_ScanDisk(int Disk) { - tVFS_Node *node; - tMBR mbr; - + Uint64 sector_count; ENTER("iDisk", Disk); // Get the disk size - gATA_Disks[ Disk ].Sectors = ATA_GetDiskSize(Disk); - if(gATA_Disks[ Disk ].Sectors == 0) + sector_count = ATA_GetDiskSize(Disk); + if(sector_count == 0) { LEAVE('i', 0); return 0; } - LOG("gATA_Disks[ %i ].Sectors = 0x%x", Disk, gATA_Disks[ Disk ].Sectors); - - // Create Name - gATA_Disks[ Disk ].Name[0] = 'A'+Disk; - gATA_Disks[ Disk ].Name[1] = '\0'; - #if 1 { - Uint64 val = gATA_Disks[ Disk ].Sectors / 2; + Uint64 val = sector_count / 2; char *units = "KiB"; if( val > 4*1024 ) { val /= 1024; @@ -169,244 +99,45 @@ int ATA_ScanDisk(int Disk) val /= 1024; units = "TiB"; } - Log_Notice("ATA", "Disk %s: 0x%llx Sectors (%lli %s)", - gATA_Disks[ Disk ].Name, gATA_Disks[ Disk ].Sectors, val, units); + Log_Notice("ATA", "Disk %i: 0x%llx Sectors (%lli %s)", + Disk, sector_count, val, units); } #endif - // Get pointer to vfs node and populate it - node = &gATA_Disks[ Disk ].Node; - node->Size = gATA_Disks[Disk].Sectors * SECTOR_SIZE; - node->NumACLs = 0; // Means Superuser only can access it - node->Inode = (Disk << 8) | 0xFF; - node->ImplPtr = gATA_Disks[ Disk ].Name; - - node->ATime = node->MTime = node->CTime = now(); + char name[] = "ata0"; + sprintf(name, "ata%i", Disk); + LVM_AddVolume(&gATA_VolType, name, (void*)(Uint*)Disk, sector_count); - node->Type = &gATA_DiskNodeType; - - // --- Scan Partitions --- - LOG("Reading MBR"); - // Read Boot Sector - if( ATA_ReadDMA( Disk, 0, 1, &mbr ) != 0 ) { - Log_Warning("ATA", "Error in reading MBR on %i", Disk); - LEAVE('i', 0); - return 0; - } - - // Check for a GPT table - if(mbr.Parts[0].SystemID == 0xEE) - ATA_ParseGPT(Disk); - else // No? Just parse the MBR - ATA_ParseMBR(Disk, &mbr); - #if DEBUG >= 2 + { + char mbr[512]; ATA_ReadDMA( Disk, 1, 1, &mbr ); Debug_HexDump("ATA_ScanDisk", &mbr, 512); + } #endif LEAVE('i', 1); return 1; } -/** - * \fn void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length) - * \brief Fills a parition's information structure - */ -void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length) -{ - ENTER("pPart iDisk iNum XStart XLength", Part, Disk, Num, Start, Length); - Part->Start = Start; - Part->Length = Length; - Part->Name[0] = 'A'+Disk; - if(Num >= 10) { - Part->Name[1] = '1'+Num/10; - Part->Name[2] = '1'+Num%10; - Part->Name[3] = '\0'; - } else { - Part->Name[1] = '1'+Num; - Part->Name[2] = '\0'; - } - Part->Node.NumACLs = 0; // Only root can read/write raw block devices - Part->Node.Inode = (Disk << 8) | Num; - Part->Node.ImplPtr = Part->Name; - - Part->Node.Type = &gATA_DiskNodeType; - Log_Notice("ATA", "Partition %s at 0x%llx+0x%llx", Part->Name, Part->Start, Part->Length); - LOG("Made '%s' (&Node=%p)", Part->Name, &Part->Node); - LEAVE('-'); -} - -/** - * \fn void ATA_ParseGPT(int Disk) - * \brief Parses the GUID Partition Table - */ -void ATA_ParseGPT(int Disk) -{ - ///\todo Support GPT Disks - Warning("GPT Disks are currently unsupported (Disk %i)", Disk); -} - -/** - * \fn char *ATA_ReadDir(tVFS_Node *Node, int Pos) - */ -char *ATA_ReadDir(tVFS_Node *UNUSED(Node), int Pos) -{ - if(Pos >= giATA_NumNodes || Pos < 0) return NULL; - return strdup( gATA_Nodes[Pos]->ImplPtr ); -} - -/** - * \fn tVFS_Node *ATA_FindDir(tVFS_Node *Node, const char *Name) - */ -tVFS_Node *ATA_FindDir(tVFS_Node *UNUSED(Node), const char *Name) -{ - int part; - tATA_Disk *disk; - - // Check first character - if(Name[0] < 'A' || Name[0] > 'A'+MAX_ATA_DISKS) - return NULL; - disk = &gATA_Disks[Name[0]-'A']; - // Raw Disk - if(Name[1] == '\0') { - if( disk->Sectors == 0 && disk->Name[0] == '\0') - return NULL; - return &disk->Node; - } - - // Partitions - if(Name[1] < '0' || '9' < Name[1]) return NULL; - if(Name[2] == '\0') { // <= 9 - part = Name[1] - '0'; - part --; - return &disk->Partitions[part].Node; - } - // > 9 - if('0' > Name[2] || '9' < Name[2]) return NULL; - if(Name[3] != '\0') return NULL; - - part = (Name[1] - '0') * 10; - part += Name[2] - '0'; - part --; - return &disk->Partitions[part].Node; - -} - -/** - * \brief Read handler for VFS interface - */ -size_t ATA_ReadFS(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer) -{ - int disk = Node->Inode >> 8; - int part = Node->Inode & 0xFF; - - ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); - - // Raw Disk Access - if(part == 0xFF) - { - if( Offset >= gATA_Disks[disk].Sectors * SECTOR_SIZE ) { - LEAVE('i', 0); - return 0; - } - if( Offset + Length > gATA_Disks[disk].Sectors*SECTOR_SIZE ) - Length = gATA_Disks[disk].Sectors*SECTOR_SIZE - Offset; - } - // Partition - else - { - if( Offset >= gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE ) { - LEAVE('i', 0); - return 0; - } - if( Offset + Length > gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE ) - Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset; - Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE; - } - - { - int ret = DrvUtil_ReadBlock( - Offset, Length, Buffer, - ATA_ReadRaw, SECTOR_SIZE, (void*)(Uint)disk - ); - //Log("ATA_ReadFS: disk=%i, Offset=%lli, Length=%lli", disk, Offset, Length); - //Debug_HexDump("ATA_ReadFS", Buffer, Length); - LEAVE('i', ret); - return ret; - } -} - -/** - * \brief Write handler for VFS interface - */ -size_t ATA_WriteFS(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer) -{ - int disk = Node->Inode >> 8; - int part = Node->Inode & 0xFF; - - // Raw Disk Access - if(part == 0xFF) - { - if( Offset >= gATA_Disks[disk].Sectors * SECTOR_SIZE ) - return 0; - if( Offset + Length > gATA_Disks[disk].Sectors*SECTOR_SIZE ) - Length = gATA_Disks[disk].Sectors*SECTOR_SIZE - Offset; - } - // Partition - else - { - if( Offset >= gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE ) - return 0; - if( Offset + Length > gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE ) - Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset; - Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE; - } - - 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, (void*)(Uint)disk - ); -} - -const char *csaATA_IOCtls[] = {DRV_IOCTLNAMES, DRV_DISK_IOCTLNAMES, NULL}; -/** - * \fn int ATA_IOCtl(tVFS_Node *Node, int Id, void *Data) - * \brief IO Control Funtion - */ -int ATA_IOCtl(tVFS_Node *UNUSED(Node), int Id, void *Data) -{ - switch(Id) - { - BASE_IOCTLS(DRV_TYPE_DISK, "i386ATA", VERSION, csaATA_IOCtls); - - case DISK_IOCTL_GETBLOCKSIZE: - return 512; - - default: - return 0; - } - return 0; -} - // --- Disk Access --- /** * \fn Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk) */ -Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, void *Argument) +int ATA_ReadRaw(void *Ptr, Uint64 Address, Uint Count, void *Buffer) { - int Disk = (tVAddr)Argument; + int Disk = (tVAddr)Ptr; int ret; Uint offset; Uint done = 0; + LOG("Reading %i sectors from 0x%llx of disk %i", Count, Address, Disk); + // Pass straight on to ATA_ReadDMAPage if we can if(Count <= MAX_DMA_SECTORS) { ret = ATA_ReadDMA(Disk, Address, Count, Buffer); - if(ret == 0) return 0; + if(ret) return 0; return Count; } @@ -423,17 +154,17 @@ Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, void *Argument) offset += MAX_DMA_SECTORS*SECTOR_SIZE; } - ret = ATA_ReadDMA(Disk, Address+offset, Count, Buffer+offset); - if(ret != 1) return 0; + ret = ATA_ReadDMA(Disk, Address+done, Count, Buffer+offset); + if(ret) return 0; return done+Count; } /** * \fn 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 ATA_WriteRaw(void *Ptr, Uint64 Address, Uint Count, const void *Buffer) { - int Disk = (tVAddr)Argument; + int Disk = (tVAddr)Ptr; int ret; Uint offset; Uint done = 0; diff --git a/KernelLand/Modules/Storage/ATA/mbr.c b/KernelLand/Modules/Storage/ATA/mbr.c deleted file mode 100644 index eca81508..00000000 --- a/KernelLand/Modules/Storage/ATA/mbr.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Acess2 IDE Harddisk Driver - * - MBR Parsing Code - * mbr.c - */ -#define DEBUG 0 -#include -#include "common.h" - -// === PROTOTYPES === -void ATA_ParseMBR(int Disk, tMBR *MBR); -Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length); - -// === GLOBALS === - -// === CODE === -/** - * \fn void ATA_ParseMBR(int Disk, tMBR *MBR) - */ -void ATA_ParseMBR(int Disk, tMBR *MBR) -{ - int i, j = 0, k = 4; - Uint64 extendedLBA; - Uint64 base, len; - - ENTER("iDisk", Disk); - - // Count Partitions - gATA_Disks[Disk].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 - { - 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, don't count - - if( MBR->Parts[i].SystemID == 0xF || MBR->Parts[i].SystemID == 5 ) { - LOG("Extended Partition at 0x%llx", base); - if(extendedLBA != 0) { - Warning("Disk %i has multiple extended partitions, ignoring rest", Disk); - continue; - } - extendedLBA = base; - } - else { - LOG("Primary Partition at 0x%llx", base); - - gATA_Disks[Disk].NumPartitions ++; - } - } - while(extendedLBA != 0) - { - extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len); - if( extendedLBA == -1 ) break; - gATA_Disks[Disk].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) ); - - // --- Fill Partition Info --- - extendedLBA = 0; - for( j = 0, i = 0; i < 4; i ++ ) - { - LOG("MBR->Parts[%i].SystemID = 0x%02x", i, MBR->Parts[i].SystemID); - if( MBR->Parts[i].SystemID == 0 ) continue; - if( MBR->Parts[i].Boot == 0x0 || MBR->Parts[i].Boot == 0x80 ) // LBA 28 - { - base = MBR->Parts[i].LBAStart; - len = MBR->Parts[i].LBALength; - } - 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; - } - else - 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; - continue; - } - // Create Partition - ATA_int_MakePartition( - &gATA_Disks[Disk].Partitions[j], Disk, j, - base, len - ); - j ++; - - } - // Scan extended partitions - while(extendedLBA != 0) - { - extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len); - if(extendedLBA == -1) break; - ATA_int_MakePartition( - &gATA_Disks[Disk].Partitions[j], Disk, k, base, len - ); - } - - LEAVE('-'); -} - -/** - * \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 link = 0; - int bFoundPart = 0;; - int i; - tMBR mbr; - Uint64 base, len; - - if( ATA_ReadDMA( Disk, Addr, 1, &mbr ) != 0 ) - return -1; // Stop on Errors - - for( i = 0; i < 4; i ++ ) - { - if( mbr.Parts[i].SystemID == 0 ) continue; - - // LBA 24 - if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 ) { - base = mbr.Parts[i].LBAStart; - len = mbr.Parts[i].LBALength; - } - // LBA 48 - else if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 ) { - base = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart; - 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 - ); - return -1; - } - base += Addr; // Addresses are relative - - switch(mbr.Parts[i].SystemID) - { - case 0xF: - case 0x5: - if(link != 0) { - Log_Warning("ATA MBR", - "Disk %i has two forward links in the extended partition", - Disk - ); - return -1; - } - link = base; - break; - default: - if(bFoundPart) { - Warning("ATA MBR", - "Disk %i has more than one partition in the extended partition at 0x%llx", - Disk, Addr - ); - return -1; - } - bFoundPart = 1; - *Base = base; - *Length = len; - break; - } - } - - if(!bFoundPart) { - Log_Warning("ATA MBR", - "No partition in extended partiton, Disk %i 0x%llx", - Disk, Addr); - return -1; - } - - return link; -} diff --git a/KernelLand/Modules/Storage/LVM/include/lvm.h b/KernelLand/Modules/Storage/LVM/include/lvm.h index 904a735b..3a9ef1b1 100644 --- a/KernelLand/Modules/Storage/LVM/include/lvm.h +++ b/KernelLand/Modules/Storage/LVM/include/lvm.h @@ -10,10 +10,20 @@ #include -typedef int (*tLVM_ReadFcn)(void *, Uint64, size_t, void *); -typedef int (*tLVM_WriteFcn)(void *, Uint64, size_t, const void *); +typedef struct sLVM_VolType tLVM_VolType; -extern int LVM_AddVolume(const char *Name, void *Ptr, size_t BlockSize, tLVM_ReadFcn Read, tLVM_WriteFcn Write); +struct sLVM_VolType +{ + const char *Name; + + size_t BlockSize; + + int (*Read)(void *, Uint64, size_t, void *); + int (*Write)(void *, Uint64, size_t, const void *); +}; + + +extern int LVM_AddVolume(const tLVM_VolType *Type, const char *Name, void *Ptr, size_t BlockCount); #endif diff --git a/KernelLand/Modules/Storage/LVM/lvm_int.h b/KernelLand/Modules/Storage/LVM/lvm_int.h index 94307367..bd077019 100644 --- a/KernelLand/Modules/Storage/LVM/lvm_int.h +++ b/KernelLand/Modules/Storage/LVM/lvm_int.h @@ -28,11 +28,9 @@ struct sLVM_Vol tVFS_Node VolNode; void *Ptr; - tLVM_ReadFcn Read; - tLVM_WriteFcn Write; + const tLVM_VolType *Type; Uint64 BlockCount; - size_t BlockSize; int nSubVolumes; tLVM_SubVolume **SubVolumes; diff --git a/KernelLand/Modules/Storage/LVM/main.c b/KernelLand/Modules/Storage/LVM/main.c index 39ce9a92..d89604a7 100644 --- a/KernelLand/Modules/Storage/LVM/main.c +++ b/KernelLand/Modules/Storage/LVM/main.c @@ -47,7 +47,7 @@ tVFS_NodeType gLVM_SubVolNodeType = { }; tDevFS_Driver gLVM_DevFS = { NULL, "LVM", - {.Flags = VFS_FFLAG_DIRECTORY, .Type = &gLVM_RootNodeType} + {.Flags = VFS_FFLAG_DIRECTORY, .Type = &gLVM_RootNodeType, .Size = -1} }; tLVM_Vol *gpLVM_FirstVolume; @@ -127,7 +127,7 @@ tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name) size_t LVM_Vol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer) { tLVM_Vol *vol = Node->ImplPtr; - Uint64 byte_size = vol->BlockCount * vol->BlockSize; + Uint64 byte_size = vol->BlockCount * vol->Type->BlockSize; if( Offset > byte_size ) return 0; @@ -138,7 +138,7 @@ size_t LVM_Vol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer) return DrvUtil_ReadBlock( Offset, Length, Buffer, - LVM_int_DrvUtil_ReadBlock, vol->BlockSize, vol + LVM_int_DrvUtil_ReadBlock, vol->Type->BlockSize, vol ); } @@ -150,7 +150,7 @@ size_t LVM_Vol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *B 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; + Uint64 byte_size = sv->BlockCount * sv->Vol->Type->BlockSize; if( Offset > byte_size ) return 0; @@ -159,17 +159,22 @@ size_t LVM_SubVol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffe if( Offset + Length > byte_size ) Length = byte_size - Offset; - Offset += sv->FirstBlock * sv->Vol->BlockSize; + LOG("Reading (0x%llx+0x%llx)+0x%x to %p", + (Uint64)(sv->FirstBlock * sv->Vol->Type->BlockSize), Offset, + Length, Buffer + ); + Offset += sv->FirstBlock * sv->Vol->Type->BlockSize; + return DrvUtil_ReadBlock( Offset, Length, Buffer, - LVM_int_DrvUtil_ReadBlock, sv->Vol->BlockSize, sv->Vol + LVM_int_DrvUtil_ReadBlock, sv->Vol->Type->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; + Uint64 byte_size = sv->BlockCount * sv->Vol->Type->BlockSize; if( Offset > byte_size ) return 0; @@ -178,12 +183,12 @@ size_t LVM_SubVol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void if( Offset + Length > byte_size ) Length = byte_size - Offset; - Offset += sv->FirstBlock * sv->Vol->BlockSize; + Offset += sv->FirstBlock * sv->Vol->Type->BlockSize; return DrvUtil_WriteBlock( Offset, Length, Buffer, LVM_int_DrvUtil_ReadBlock, LVM_int_DrvUtil_WriteBlock, - sv->Vol->BlockSize, sv->Vol + sv->Vol->Type->BlockSize, sv->Vol ); } diff --git a/KernelLand/Modules/Storage/LVM/volumes.c b/KernelLand/Modules/Storage/LVM/volumes.c index bd0b530e..35054987 100644 --- a/KernelLand/Modules/Storage/LVM/volumes.c +++ b/KernelLand/Modules/Storage/LVM/volumes.c @@ -5,6 +5,7 @@ * volumes.c * - Volume management */ +#define DEBUG 1 #include "lvm_int.h" // === PROTOTYPES === @@ -18,39 +19,41 @@ int LVM_AddVolumeVFS(const char *Name, int FD) { // Assuming 512-byte blocks, not a good idea - return LVM_AddVolume(Name, (void*)(Uint)FD, 512, LVM_int_VFSReadEmul, LVM_int_VFSWriteEmul); +// return LVM_AddVolume(Name, (void*)(Uint)FD, 512, LVM_int_VFSReadEmul, LVM_int_VFSWriteEmul); + return 0; } -int LVM_AddVolume(const char *Name, void *Ptr, size_t BlockSize, tLVM_ReadFcn Read, tLVM_WriteFcn Write) +int LVM_AddVolume(const tLVM_VolType *Type, const char *Name, void *Ptr, size_t BlockCount) { tLVM_Vol dummy_vol; tLVM_Vol *real_vol; - tLVM_Format *type; + tLVM_Format *fmt; void *first_block; + dummy_vol.Type = Type; dummy_vol.Ptr = Ptr; - dummy_vol.Read = Read; - dummy_vol.Write = Write; - dummy_vol.BlockSize = BlockSize; + dummy_vol.BlockCount = BlockCount; // Read the first block of the volume - first_block = malloc(BlockSize); - Read(Ptr, 0, 1, first_block); + LOG("Type->BlockSize = %i", Type->BlockSize); + first_block = malloc(Type->BlockSize); + LOG("first_block = %p", first_block); + Type->Read(Ptr, 0, 1, first_block); + LOG("first block read"); - // Determine Type - // TODO: Determine type - type = &gLVM_MBRType; + // Determine Format + // TODO: Determine format + fmt = &gLVM_MBRType; // Type->CountSubvolumes - dummy_vol.nSubVolumes = type->CountSubvolumes(&dummy_vol, first_block); + dummy_vol.nSubVolumes = fmt->CountSubvolumes(&dummy_vol, first_block); // Create real volume descriptor // TODO: If this needs to be rescanned later, having the subvolume list separate might be an idea real_vol = malloc( sizeof(tLVM_Vol) + strlen(Name) + 1 + sizeof(tLVM_SubVolume*) * dummy_vol.nSubVolumes ); + real_vol->Type = Type; real_vol->Ptr = Ptr; - real_vol->Read = Read; - real_vol->Write = Write; - real_vol->BlockSize = BlockSize; + real_vol->BlockCount = BlockCount; real_vol->nSubVolumes = dummy_vol.nSubVolumes; real_vol->SubVolumes = (void*)( real_vol->Name + strlen(Name) + 1 ); strcpy(real_vol->Name, Name); @@ -60,13 +63,14 @@ int LVM_AddVolume(const char *Name, void *Ptr, size_t BlockSize, tLVM_ReadFcn Re real_vol->DirNode.Type = &gLVM_VolNodeType; real_vol->DirNode.ImplPtr = real_vol; real_vol->DirNode.Flags = VFS_FFLAG_DIRECTORY; + real_vol->DirNode.Size = -1; memset(&real_vol->VolNode, 0, sizeof(tVFS_Node)); real_vol->VolNode.Type = &gLVM_VolNodeType; real_vol->VolNode.ImplPtr = real_vol; - real_vol->VolNode.Flags = VFS_FFLAG_DIRECTORY; + real_vol->VolNode.Size = BlockCount * Type->BlockSize; // Type->PopulateSubvolumes - type->PopulateSubvolumes(real_vol, first_block); + fmt->PopulateSubvolumes(real_vol, first_block); free(first_block); // Add to volume list @@ -109,6 +113,10 @@ void LVM_int_SetSubvolume_Anon(tLVM_Vol *Volume, int Index, Uint64 FirstBlock, U sv->Node.ImplPtr = sv; sv->Node.Type = &gLVM_SubVolNodeType; + sv->Node.Size = BlockCount * Volume->Type->BlockSize; + + Log_Log("LVM", "Partition %s/%s - 0x%llx+0x%llx blocks", + Volume->Name, sv->Name, FirstBlock, BlockCount); } // -------------------------------------------------------------------- @@ -116,12 +124,12 @@ void LVM_int_SetSubvolume_Anon(tLVM_Vol *Volume, int Index, Uint64 FirstBlock, U // -------------------------------------------------------------------- size_t LVM_int_ReadVolume(tLVM_Vol *Volume, Uint64 BlockNum, size_t BlockCount, void *Dest) { - return Volume->Read(Volume->Ptr, BlockNum, BlockCount, Dest); + return Volume->Type->Read(Volume->Ptr, BlockNum, BlockCount, Dest); } size_t LVM_int_WriteVolume(tLVM_Vol *Volume, Uint64 BlockNum, size_t BlockCount, const void *Src) { - return Volume->Write(Volume->Ptr, BlockNum, BlockCount, Src); + return Volume->Type->Write(Volume->Ptr, BlockNum, BlockCount, Src); } int LVM_int_VFSReadEmul(void *Arg, Uint64 BlockStart, size_t BlockCount, void *Dest) -- 2.20.1