Modules - Working on LVM layer (not integrated yet)
[tpg/acess2.git] / KernelLand / Modules / Storage / LVM / main.c
1 /*
2  * Acess2 Logical Volume Manager
3  * - By John Hodge (thePowersGang)
4  *
5  * lvm.h
6  * - LVM Core definitions
7  */
8 #define DEBUG   0
9 #define VERSION VER2(0,1)
10 #include "lvm_int.h"
11 #include <fs_devfs.h>
12 #include <modules.h>
13 #include <api_drv_disk.h>
14
15 // === PROTOTYPES ===
16 // ---
17  int    LVM_Initialise(char **Arguments);
18 void    LVM_Cleanup(void);
19 // ---
20 char    *LVM_Root_ReadDir(tVFS_Node *Node, int ID);
21 tVFS_Node       *LVM_Root_FindDir(tVFS_Node *Node, const char *Name);
22 char    *LVM_Vol_ReadDir(tVFS_Node *Node, int ID);
23 tVFS_Node       *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name);
24 size_t  LVM_SubVol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
25 size_t  LVM_SubVol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
26
27 Uint    LVM_int_DrvUtil_ReadBlock(Uint64 Address, Uint Count, void *Buffer, void *Argument);
28 Uint    LVM_int_DrvUtil_WriteBlock(Uint64 Address, Uint Count, const void *Buffer, void *Argument);
29
30 // === GLOBALS ===
31 MODULE_DEFINE(0, VERSION, LVM, LVM_Initialise, LVM_Cleanup, NULL);
32 tVFS_NodeType   gLVM_RootNodeType = {
33         .ReadDir = LVM_Root_ReadDir,
34         .FindDir = LVM_Root_FindDir
35 };
36 tVFS_NodeType   gLVM_VolNodeType = {
37         .ReadDir = LVM_Vol_ReadDir,
38         .FindDir = LVM_Vol_FindDir
39 };
40 tVFS_NodeType   gLVM_SubVolNodeType = {
41         .Read = LVM_SubVol_Read,
42         .Write = LVM_SubVol_Write
43 };
44 tDevFS_Driver   gLVM_DevFS = {
45         NULL, "LVM",
46         {.Flags = VFS_FFLAG_DIRECTORY, .Type = &gLVM_RootNodeType}
47 };
48
49 tLVM_Vol        *gpLVM_FirstVolume;
50 tLVM_Vol        *gpLVM_LastVolume = (void*)&gpLVM_FirstVolume;
51
52 // === CODE ===
53 int LVM_Initialise(char **Arguments)
54 {
55         DevFS_AddDevice( &gLVM_DevFS );
56         return 0;
57 }
58
59 void LVM_Cleanup(void)
60 {
61         
62 }
63
64 // --------------------------------------------------------------------
65 // VFS Inteface
66 // --------------------------------------------------------------------
67 char *LVM_Root_ReadDir(tVFS_Node *Node, int ID)
68 {
69         tLVM_Vol        *vol;
70         
71         if( ID < 0 )    return NULL;    
72
73         for( vol = gpLVM_FirstVolume; vol && ID --; vol = vol->Next );
74         
75         if(vol)
76                 return strdup(vol->Name);
77         else
78                 return NULL;
79 }
80 tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name)
81 {
82         tLVM_Vol        *vol;
83         for( vol = gpLVM_FirstVolume; vol; vol = vol->Next )
84         {
85                 if( strcmp(vol->Name, Name) == 0 )
86                 {
87                         return &vol->Node;
88                 }
89         }
90         return NULL;
91 }
92
93 char *LVM_Vol_ReadDir(tVFS_Node *Node, int ID)
94 {
95         tLVM_Vol        *vol = Node->ImplPtr;
96         
97         if( ID < 0 || ID >= vol->nSubVolumes )
98                 return NULL;
99         
100         return strdup( vol->SubVolumes[ID]->Name );
101 }
102 tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name)
103 {
104         tLVM_Vol        *vol = Node->ImplPtr;
105         
106         for( int i = 0; i < vol->nSubVolumes; i ++ )
107         {
108                 if( strcmp(vol->SubVolumes[i]->Name, Name) == 0 )
109                 {
110                         return &vol->SubVolumes[i]->Node;
111                 }
112         }
113
114         return NULL;
115 }
116
117 size_t LVM_SubVol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
118 {
119         tLVM_SubVolume  *sv = Node->ImplPtr;
120         Uint64  byte_size = sv->BlockCount * sv->Vol->BlockSize;
121
122         if( Offset > byte_size )
123                 return 0;
124         if( Length > byte_size )
125                 Length = byte_size;
126         if( Offset + Length > byte_size )
127                 Length = byte_size - Offset;
128
129         Offset += sv->FirstBlock * sv->Vol->BlockSize;  
130         
131         return DrvUtil_ReadBlock(
132                 Offset, Length, Buffer, 
133                 LVM_int_DrvUtil_ReadBlock, sv->Vol->BlockSize, sv->Vol
134                 );
135 }
136 size_t LVM_SubVol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)
137 {
138         tLVM_SubVolume  *sv = Node->ImplPtr;
139         Uint64  byte_size = sv->BlockCount * sv->Vol->BlockSize;
140
141         if( Offset > byte_size )
142                 return 0;
143         if( Length > byte_size )
144                 Length = byte_size;
145         if( Offset + Length > byte_size )
146                 Length = byte_size - Offset;
147
148         Offset += sv->FirstBlock * sv->Vol->BlockSize;  
149         
150         return DrvUtil_WriteBlock(
151                 Offset, Length, Buffer,
152                 LVM_int_DrvUtil_ReadBlock, LVM_int_DrvUtil_WriteBlock,
153                 sv->Vol->BlockSize, sv->Vol
154                 );
155 }
156
157 Uint LVM_int_DrvUtil_ReadBlock(Uint64 Address, Uint Count, void *Buffer, void *Argument)
158 {
159         return LVM_int_ReadVolume( Argument, Address, Count, Buffer );
160 }
161
162 Uint LVM_int_DrvUtil_WriteBlock(Uint64 Address, Uint Count, const void *Buffer, void *Argument)
163 {
164         return LVM_int_WriteVolume( Argument, Address, Count, Buffer );
165 }
166

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