2 * Acess2 Logical Volume Manager
3 * - By John Hodge (thePowersGang)
14 int LVM_MBR_CountSubvolumes(tLVM_Vol *Volume, void *FirstSector);
15 void LVM_MBR_PopulateSubvolumes(tLVM_Vol *Volume, void *FirstSector);
16 Uint64 LVM_MBR_int_ReadExt(tLVM_Vol *Volume, Uint64 Addr, Uint64 *Base, Uint64 *Length);
22 * \brief Initialise a volume as
24 int LVM_MBR_CountSubvolumes(tLVM_Vol *Volume, void *FirstSector)
26 tMBR *MBR = FirstSector;
30 int numPartitions = 0;
32 ENTER("pVolume pFirstSector", Volume, FirstSector);
37 for( i = 0; i < 4; i ++ )
39 if( MBR->Parts[i].SystemID == 0 ) continue;
41 if( MBR->Parts[i].Boot == 0x0 || MBR->Parts[i].Boot == 0x80 ) // LBA 28
43 base = MBR->Parts[i].LBAStart;
45 else if( MBR->Parts[i].Boot == 0x1 || MBR->Parts[i].Boot == 0x81 ) // LBA 48
47 base = (MBR->Parts[i].StartHi << 16) | MBR->Parts[i].LBAStart;
50 continue ; // Invalid, so don't count
52 if( MBR->Parts[i].SystemID == 0xF || MBR->Parts[i].SystemID == 5 )
54 LOG("Extended Partition at 0x%llx", base);
55 if(extendedLBA != 0) {
58 "Volume %p has multiple extended partitions, ignoring all but first",
67 LOG("Primary Partition at 0x%llx", base);
71 while(extendedLBA != 0)
73 extendedLBA = LVM_MBR_int_ReadExt(Volume, extendedLBA, &base, &len);
74 if( extendedLBA == -1 ) break;
77 LOG("numPartitions = %i", numPartitions);
79 LEAVE('i', numPartitions);
83 void LVM_MBR_PopulateSubvolumes(tLVM_Vol *Volume, void *FirstSector)
88 tMBR *MBR = FirstSector;
90 ENTER("pVolume pFirstSector", Volume, FirstSector);
92 // --- Fill Partition Info ---
94 for( j = 0, i = 0; i < 4; i ++ )
96 LOG("MBR->Parts[%i].SystemID = 0x%02x", i, MBR->Parts[i].SystemID);
97 if( MBR->Parts[i].SystemID == 0 ) continue;
98 if( MBR->Parts[i].Boot == 0x0 || MBR->Parts[i].Boot == 0x80 ) // LBA 28
100 base = MBR->Parts[i].LBAStart;
101 len = MBR->Parts[i].LBALength;
103 else if( MBR->Parts[i].Boot == 0x1 || MBR->Parts[i].Boot == 0x81 ) // LBA 48
105 base = (MBR->Parts[i].StartHi << 16) | MBR->Parts[i].LBAStart;
106 len = (MBR->Parts[i].LengthHi << 16) | MBR->Parts[i].LBALength;
111 if( MBR->Parts[i].SystemID == 0xF || MBR->Parts[i].SystemID == 5 ) {
117 LVM_int_SetSubvolume_Anon( Volume, j, base, len );
121 // Scan extended partitions
122 while(extendedLBA != 0)
124 extendedLBA = LVM_MBR_int_ReadExt(Volume, extendedLBA, &base, &len);
125 if(extendedLBA == -1) break;
126 LVM_int_SetSubvolume_Anon( Volume, j, base, len );
134 * \brief Reads an extended partition
135 * \return LBA of next Extended, -1 on error, 0 for last
137 Uint64 LVM_MBR_int_ReadExt(tLVM_Vol *Volume, Uint64 Addr, Uint64 *Base, Uint64 *Length)
145 // TODO: Handle non-512 byte sectors
146 if( LVM_int_ReadVolume( Volume, Addr, 1, &mbr ) != 0 )
147 return -1; // Stop on Errors
149 for( i = 0; i < 4; i ++ )
151 if( mbr.Parts[i].SystemID == 0 ) continue;
154 if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 ) {
155 base = mbr.Parts[i].LBAStart;
156 len = mbr.Parts[i].LBALength;
159 else if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 ) {
160 base = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
161 len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength;
164 Log_Warning("LVM MBR",
165 "Unknown partition type 0x%x, Volume %p Ext 0x%llx Part %i",
166 mbr.Parts[i].Boot, Volume, Addr, i
171 switch(mbr.Parts[i].SystemID)
176 Log_Warning("LVM MBR",
177 "Volume %p has two forward links in the extended partition",
187 "Volume %p has more than one partition in the extended partition at 0x%llx",
193 *Base = Addr + base; // Extended partitions are based off the sub-mbr
200 Log_Warning("LVM MBR",
201 "No partition in extended partiton, Volume %p 0x%llx",