#include <api_drv_common.h>
#include <api_drv_disk.h>
#include "common.h"
+#include <Storage/LVM/include/lvm.h>
// === MACROS ===
#define IO_DELAY() do{inb(0x80); inb(0x80); inb(0x80); inb(0x80);}while(0)
// === 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 ===
/**
ATA_SetupPartitions();
- ATA_SetupVFS();
-
- if( DevFS_AddDevice( &gATA_DriverInfo ) == 0 )
- return MODULE_ERR_MISC;
-
return MODULE_ERR_OK;
}
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;
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;
}
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;
+++ /dev/null
-/*
- * Acess2 IDE Harddisk Driver
- * - MBR Parsing Code
- * mbr.c
- */
-#define DEBUG 0
-#include <acess.h>
-#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;
-}
* volumes.c
* - Volume management
*/
+#define DEBUG 1
#include "lvm_int.h"
// === PROTOTYPES ===
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);
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
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);
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
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)