Modules - Working on LVM layer (not integrated yet)
[tpg/acess2.git] / KernelLand / Modules / Storage / LVM / main.c
index e69de29..587689e 100644 (file)
@@ -0,0 +1,166 @@
+/*
+ * Acess2 Logical Volume Manager
+ * - By John Hodge (thePowersGang)
+ *
+ * lvm.h
+ * - LVM Core definitions
+ */
+#define DEBUG  0
+#define VERSION        VER2(0,1)
+#include "lvm_int.h"
+#include <fs_devfs.h>
+#include <modules.h>
+#include <api_drv_disk.h>
+
+// === PROTOTYPES ===
+// ---
+ int   LVM_Initialise(char **Arguments);
+void   LVM_Cleanup(void);
+// ---
+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_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);
+
+Uint   LVM_int_DrvUtil_ReadBlock(Uint64 Address, Uint Count, void *Buffer, void *Argument);
+Uint   LVM_int_DrvUtil_WriteBlock(Uint64 Address, Uint Count, const void *Buffer, void *Argument);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, LVM, LVM_Initialise, LVM_Cleanup, NULL);
+tVFS_NodeType  gLVM_RootNodeType = {
+       .ReadDir = LVM_Root_ReadDir,
+       .FindDir = LVM_Root_FindDir
+};
+tVFS_NodeType  gLVM_VolNodeType = {
+       .ReadDir = LVM_Vol_ReadDir,
+       .FindDir = LVM_Vol_FindDir
+};
+tVFS_NodeType  gLVM_SubVolNodeType = {
+       .Read = LVM_SubVol_Read,
+       .Write = LVM_SubVol_Write
+};
+tDevFS_Driver  gLVM_DevFS = {
+       NULL, "LVM",
+       {.Flags = VFS_FFLAG_DIRECTORY, .Type = &gLVM_RootNodeType}
+};
+
+tLVM_Vol       *gpLVM_FirstVolume;
+tLVM_Vol       *gpLVM_LastVolume = (void*)&gpLVM_FirstVolume;
+
+// === CODE ===
+int LVM_Initialise(char **Arguments)
+{
+       DevFS_AddDevice( &gLVM_DevFS );
+       return 0;
+}
+
+void LVM_Cleanup(void)
+{
+       
+}
+
+// --------------------------------------------------------------------
+// VFS Inteface
+// --------------------------------------------------------------------
+char *LVM_Root_ReadDir(tVFS_Node *Node, int ID)
+{
+       tLVM_Vol        *vol;
+       
+       if( ID < 0 )    return NULL;    
+
+       for( vol = gpLVM_FirstVolume; vol && ID --; vol = vol->Next );
+       
+       if(vol)
+               return strdup(vol->Name);
+       else
+               return NULL;
+}
+tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name)
+{
+       tLVM_Vol        *vol;
+       for( vol = gpLVM_FirstVolume; vol; vol = vol->Next )
+       {
+               if( strcmp(vol->Name, Name) == 0 )
+               {
+                       return &vol->Node;
+               }
+       }
+       return NULL;
+}
+
+char *LVM_Vol_ReadDir(tVFS_Node *Node, int ID)
+{
+       tLVM_Vol        *vol = Node->ImplPtr;
+       
+       if( ID < 0 || ID >= vol->nSubVolumes )
+               return NULL;
+       
+       return strdup( vol->SubVolumes[ID]->Name );
+}
+tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name)
+{
+       tLVM_Vol        *vol = Node->ImplPtr;
+       
+       for( int i = 0; i < vol->nSubVolumes; i ++ )
+       {
+               if( strcmp(vol->SubVolumes[i]->Name, Name) == 0 )
+               {
+                       return &vol->SubVolumes[i]->Node;
+               }
+       }
+
+       return NULL;
+}
+
+size_t LVM_SubVol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
+{
+       tLVM_SubVolume  *sv = Node->ImplPtr;
+       Uint64  byte_size = sv->BlockCount * sv->Vol->BlockSize;
+
+       if( Offset > byte_size )
+               return 0;
+       if( Length > byte_size )
+               Length = byte_size;
+       if( Offset + Length > byte_size )
+               Length = byte_size - Offset;
+
+       Offset += sv->FirstBlock * sv->Vol->BlockSize;  
+       
+       return DrvUtil_ReadBlock(
+               Offset, Length, Buffer, 
+               LVM_int_DrvUtil_ReadBlock, sv->Vol->BlockSize, sv->Vol
+               );
+}
+size_t LVM_SubVol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)
+{
+       tLVM_SubVolume  *sv = Node->ImplPtr;
+       Uint64  byte_size = sv->BlockCount * sv->Vol->BlockSize;
+
+       if( Offset > byte_size )
+               return 0;
+       if( Length > byte_size )
+               Length = byte_size;
+       if( Offset + Length > byte_size )
+               Length = byte_size - Offset;
+
+       Offset += sv->FirstBlock * sv->Vol->BlockSize;  
+       
+       return DrvUtil_WriteBlock(
+               Offset, Length, Buffer,
+               LVM_int_DrvUtil_ReadBlock, LVM_int_DrvUtil_WriteBlock,
+               sv->Vol->BlockSize, sv->Vol
+               );
+}
+
+Uint LVM_int_DrvUtil_ReadBlock(Uint64 Address, Uint Count, void *Buffer, void *Argument)
+{
+       return LVM_int_ReadVolume( Argument, Address, Count, Buffer );
+}
+
+Uint LVM_int_DrvUtil_WriteBlock(Uint64 Address, Uint Count, const void *Buffer, void *Argument)
+{
+       return LVM_int_WriteVolume( Argument, Address, Count, Buffer );
+}
+

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