Modules/LVM - Seriously working on it after the network API change
authorJohn Hodge <[email protected]>
Fri, 18 May 2012 16:02:12 +0000 (00:02 +0800)
committerJohn Hodge <[email protected]>
Fri, 18 May 2012 16:02:12 +0000 (00:02 +0800)
KernelLand/Modules/Storage/LVM/include/lvm.h
KernelLand/Modules/Storage/LVM/lvm.h
KernelLand/Modules/Storage/LVM/lvm_int.h
KernelLand/Modules/Storage/LVM/main.c
KernelLand/Modules/Storage/LVM/mbr.c
KernelLand/Modules/Storage/LVM/volumes.c

index 3115b61..904a735 100644 (file)
@@ -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
 
index 0d0a252..e406a9b 100644 (file)
 
 // === 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
 
index f4ef3c1..9430736 100644 (file)
@@ -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
 
index 587689e..39ce9a9 100644 (file)
@@ -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;
index 169f6f3..c137a8a 100644 (file)
@@ -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 ===
 /**
index 558a7aa..bd0b530 100644 (file)
 // --------------------------------------------------------------------
 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;
 }

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