From 2188ee53c02fc249c3f6ee8a08758e940024d754 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 19 May 2012 00:02:12 +0800 Subject: [PATCH] Modules/LVM - Seriously working on it after the network API change --- KernelLand/Modules/Storage/LVM/include/lvm.h | 2 +- KernelLand/Modules/Storage/LVM/lvm.h | 13 ++++++ KernelLand/Modules/Storage/LVM/lvm_int.h | 8 +++- KernelLand/Modules/Storage/LVM/main.c | 43 +++++++++++++++++--- KernelLand/Modules/Storage/LVM/mbr.c | 5 +++ KernelLand/Modules/Storage/LVM/volumes.c | 40 ++++++++++++++++-- 6 files changed, 101 insertions(+), 10 deletions(-) diff --git a/KernelLand/Modules/Storage/LVM/include/lvm.h b/KernelLand/Modules/Storage/LVM/include/lvm.h index 3115b619..904a735b 100644 --- a/KernelLand/Modules/Storage/LVM/include/lvm.h +++ b/KernelLand/Modules/Storage/LVM/include/lvm.h @@ -13,7 +13,7 @@ typedef int (*tLVM_ReadFcn)(void *, Uint64, size_t, void *); typedef int (*tLVM_WriteFcn)(void *, Uint64, size_t, const void *); -extern int LVM_AddVolume(const char *Name, void *Ptr, tLVM_ReadFcn Read, tLVM_WriteFcn Write); +extern int LVM_AddVolume(const char *Name, void *Ptr, size_t BlockSize, tLVM_ReadFcn Read, tLVM_WriteFcn Write); #endif diff --git a/KernelLand/Modules/Storage/LVM/lvm.h b/KernelLand/Modules/Storage/LVM/lvm.h index 0d0a2529..e406a9bb 100644 --- a/KernelLand/Modules/Storage/LVM/lvm.h +++ b/KernelLand/Modules/Storage/LVM/lvm.h @@ -12,6 +12,16 @@ // === TYPES === typedef struct sLVM_Vol tLVM_Vol; +typedef struct sLVM_Format tLVM_Format; + +// === STRUCTURES === +struct sLVM_Format +{ + tLVM_Format *Next; + const char *Name; + int (*CountSubvolumes)(tLVM_Vol *Volume, void *FirstBlockData); + void (*PopulateSubvolumes)(tLVM_Vol *Volume, void *FirstBlockData); +}; // === FUNCTIONS === extern size_t LVM_int_ReadVolume(tLVM_Vol *Volume, Uint64 BlockNum, size_t BlockCount, void *Dest); @@ -20,5 +30,8 @@ extern size_t LVM_int_WriteVolume(tLVM_Vol *Volume, Uint64 BlockNum, size_t Bloc // --- Subvolume Management --- extern void LVM_int_SetSubvolume_Anon(tLVM_Vol *Volume, int Index, Uint64 FirstBlock, Uint64 LastBlock); +// --- Global Fromats --- +extern tLVM_Format gLVM_MBRType; + #endif diff --git a/KernelLand/Modules/Storage/LVM/lvm_int.h b/KernelLand/Modules/Storage/LVM/lvm_int.h index f4ef3c12..94307367 100644 --- a/KernelLand/Modules/Storage/LVM/lvm_int.h +++ b/KernelLand/Modules/Storage/LVM/lvm_int.h @@ -24,12 +24,14 @@ struct sLVM_Vol { tLVM_Vol *Next; - tVFS_Node Node; + tVFS_Node DirNode; + tVFS_Node VolNode; void *Ptr; tLVM_ReadFcn Read; tLVM_WriteFcn Write; + Uint64 BlockCount; size_t BlockSize; int nSubVolumes; @@ -52,6 +54,10 @@ struct sLVM_SubVolume }; extern tVFS_NodeType gLVM_SubVolNodeType; +extern tVFS_NodeType gLVM_VolNodeType; + +extern tLVM_Vol *gpLVM_FirstVolume; +extern tLVM_Vol *gpLVM_LastVolume; #endif diff --git a/KernelLand/Modules/Storage/LVM/main.c b/KernelLand/Modules/Storage/LVM/main.c index 587689ef..39ce9a92 100644 --- a/KernelLand/Modules/Storage/LVM/main.c +++ b/KernelLand/Modules/Storage/LVM/main.c @@ -21,6 +21,8 @@ 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_Vol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer); +size_t LVM_Vol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer); 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); @@ -35,7 +37,9 @@ tVFS_NodeType gLVM_RootNodeType = { }; tVFS_NodeType gLVM_VolNodeType = { .ReadDir = LVM_Vol_ReadDir, - .FindDir = LVM_Vol_FindDir + .FindDir = LVM_Vol_FindDir, + .Read = LVM_Vol_Read, + .Write = LVM_Vol_Write }; tVFS_NodeType gLVM_SubVolNodeType = { .Read = LVM_SubVol_Read, @@ -84,7 +88,7 @@ tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name) { if( strcmp(vol->Name, Name) == 0 ) { - return &vol->Node; + return &vol->DirNode; } } return NULL; @@ -94,14 +98,20 @@ char *LVM_Vol_ReadDir(tVFS_Node *Node, int ID) { tLVM_Vol *vol = Node->ImplPtr; - if( ID < 0 || ID >= vol->nSubVolumes ) + if( ID < 0 || ID >= vol->nSubVolumes+1 ) return NULL; - - return strdup( vol->SubVolumes[ID]->Name ); + + if( ID == 0 ) + return strdup(".volume"); + else + return strdup( vol->SubVolumes[ID-1]->Name ); } tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name) { tLVM_Vol *vol = Node->ImplPtr; + + if( strcmp(".volume", Name) == 0 ) + return &vol->VolNode; for( int i = 0; i < vol->nSubVolumes; i ++ ) { @@ -114,6 +124,29 @@ tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name) return NULL; } +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; + + if( Offset > byte_size ) + return 0; + if( Length > byte_size ) + Length = byte_size; + if( Offset + Length > byte_size ) + Length = byte_size - Offset; + + return DrvUtil_ReadBlock( + Offset, Length, Buffer, + LVM_int_DrvUtil_ReadBlock, vol->BlockSize, vol + ); +} + +size_t LVM_Vol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer) +{ + return 0; +} + size_t LVM_SubVol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer) { tLVM_SubVolume *sv = Node->ImplPtr; diff --git a/KernelLand/Modules/Storage/LVM/mbr.c b/KernelLand/Modules/Storage/LVM/mbr.c index 169f6f36..c137a8a1 100644 --- a/KernelLand/Modules/Storage/LVM/mbr.c +++ b/KernelLand/Modules/Storage/LVM/mbr.c @@ -16,6 +16,11 @@ 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 === /** diff --git a/KernelLand/Modules/Storage/LVM/volumes.c b/KernelLand/Modules/Storage/LVM/volumes.c index 558a7aa4..bd0b530e 100644 --- a/KernelLand/Modules/Storage/LVM/volumes.c +++ b/KernelLand/Modules/Storage/LVM/volumes.c @@ -17,27 +17,61 @@ // -------------------------------------------------------------------- int LVM_AddVolumeVFS(const char *Name, int FD) { - return LVM_AddVolume(Name, (void*)(Uint)FD, LVM_int_VFSReadEmul, LVM_int_VFSWriteEmul); + // Assuming 512-byte blocks, not a good idea + return LVM_AddVolume(Name, (void*)(Uint)FD, 512, LVM_int_VFSReadEmul, LVM_int_VFSWriteEmul); } -int LVM_AddVolume(const char *Name, void *Ptr, tLVM_ReadFcn Read, tLVM_WriteFcn Write) +int LVM_AddVolume(const char *Name, void *Ptr, size_t BlockSize, tLVM_ReadFcn Read, tLVM_WriteFcn Write) { tLVM_Vol dummy_vol; -// tLVM_Vol *real_vol; + tLVM_Vol *real_vol; + tLVM_Format *type; + void *first_block; dummy_vol.Ptr = Ptr; dummy_vol.Read = Read; dummy_vol.Write = Write; + dummy_vol.BlockSize = BlockSize; + + // Read the first block of the volume + first_block = malloc(BlockSize); + Read(Ptr, 0, 1, first_block); // Determine Type + // TODO: Determine type + type = &gLVM_MBRType; // Type->CountSubvolumes + dummy_vol.nSubVolumes = type->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->Ptr = Ptr; + real_vol->Read = Read; + real_vol->Write = Write; + real_vol->BlockSize = BlockSize; + real_vol->nSubVolumes = dummy_vol.nSubVolumes; + real_vol->SubVolumes = (void*)( real_vol->Name + strlen(Name) + 1 ); + strcpy(real_vol->Name, Name); + memset(real_vol->SubVolumes, 0, sizeof(tLVM_SubVolume*) * real_vol->nSubVolumes); + // - VFS Nodes + memset(&real_vol->DirNode, 0, sizeof(tVFS_Node)); + real_vol->DirNode.Type = &gLVM_VolNodeType; + real_vol->DirNode.ImplPtr = real_vol; + real_vol->DirNode.Flags = VFS_FFLAG_DIRECTORY; + 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; // Type->PopulateSubvolumes + type->PopulateSubvolumes(real_vol, first_block); + free(first_block); // Add to volume list + gpLVM_LastVolume->Next = real_vol; + gpLVM_LastVolume = real_vol; return 0; } -- 2.20.1