Modules/LVM - Framework for partitioning type detection
[tpg/acess2.git] / KernelLand / Modules / Storage / LVM / mbr.c
index 8cbb5b1..78d3d24 100644 (file)
 /*
- * Acess2 IDE Harddisk Driver
- * - MBR Parsing Code
+ * Acess2 Logical Volume Manager
+ * - By John Hodge (thePowersGang)
+ * 
  * mbr.c
+ * - MBR Parsing Code
  */
 #define DEBUG  0
 #include <acess.h>
-#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_Detect(tLVM_Vol *Volume);
+ 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 ===
+tLVM_Format    gLVM_MBRType = {
+       .Name = "MBR",
+       .CountSubvolumes = LVM_MBR_CountSubvolumes,
+       .PopulateSubvolumes = LVM_MBR_PopulateSubvolumes
+};
 
 // === CODE ===
+int LVM_MBR_Detect(tLVM_Vol *Volume)
+{
+       tMBR    mbr;
+       // TODO: handle non-512 byte sectors
+       if( LVM_int_ReadVolume( Volume, 0, 1, &mbr ) != 0 )
+               return -1;      // Stop on Errors
+
+       if( mbr.BootFlag != LittleEndian16(0xAA55) )
+               return 0;
+
+       return 1;
+}
+
 /**
- * \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;
        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 ++ )
+       for( int 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
                {
-                       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;
+                       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 )
+               {
+                       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)
+       // Detect the GPT protector
+       if( extendedLBA == 0 && numPartitions == 1 && MBR->Parts[0].SystemID == 0xEE )
        {
-               extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len);
-               if( extendedLBA == -1 ) break;
-               gATA_Disks[Disk].NumPartitions ++;
+               // TODO: Hand off to GPT parsing code
+               Log_Warning("LBA MBR", "TODO: Hand off to GPT");
        }
-       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) );
+       // Handle extended partions
+       while(extendedLBA != 0)
+       {
+               extendedLBA = LVM_MBR_int_ReadExt(Volume, extendedLBA, &base, &len);
+               if( extendedLBA == (Uint64)-1 )
+                       break;
+               numPartitions ++;
+       }
+       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 +127,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 +136,23 @@ 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);
-               if(extendedLBA == -1)   break;
-               ATA_int_MakePartition(
-                       &gATA_Disks[Disk].Partitions[j], Disk, k, base, len
-                       );
+               extendedLBA = LVM_MBR_int_ReadExt(Volume, extendedLBA, &base, &len);
+               if(extendedLBA == (Uint64)-1)
+                       break;
+               LVM_int_SetSubvolume_Anon( Volume, j, base, len );
+               j ++ ;
        }
        
        LEAVE('-');
@@ -114,7 +162,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 +170,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 +189,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 +201,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 +211,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;
        }
        

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