* Acess2 Logical Volume Manager
* - By John Hodge (thePowersGang)
*
- * lvm.h
- * - LVM Core definitions
+ * main.c
+ * - LVM Core Code
*/
-#define DEBUG 1
+#define DEBUG 0
#define VERSION VER2(0,1)
#include "lvm_int.h"
#include <fs_devfs.h>
int LVM_Initialise(char **Arguments);
int 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_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);
+ int LVM_Root_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
+tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name, Uint Flags);
+ int LVM_Vol_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
+tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name, Uint Flags);
+size_t LVM_Vol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags);
+size_t LVM_Vol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags);
+size_t LVM_SubVol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags);
+size_t LVM_SubVol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags);
+void LVM_CloseNode(tVFS_Node *Node);
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);
.ReadDir = LVM_Vol_ReadDir,
.FindDir = LVM_Vol_FindDir,
.Read = LVM_Vol_Read,
- .Write = LVM_Vol_Write
+ .Write = LVM_Vol_Write,
+ .Close = LVM_CloseNode
};
tVFS_NodeType gLVM_SubVolNodeType = {
.Read = LVM_SubVol_Read,
- .Write = LVM_SubVol_Write
+ .Write = LVM_SubVol_Write,
+ .Close = LVM_CloseNode
};
tDevFS_Driver gLVM_DevFS = {
NULL, "LVM",
if(sv->Node.ReferenceCount == 0) {
nFree ++;
vol->SubVolumes[i] = NULL;
+ Mutex_Release(&sv->Node.Lock);
}
- Mutex_Release(&sv->Node.Lock);
-
+ else {
+ Mutex_Release(&sv->Node.Lock);
+ continue ;
+ }
+
Mutex_Acquire(&sv->Node.Lock);
LOG("Removed subvolume %s:%s", vol->Name, sv->Name);
free(sv);
Mutex_Acquire(&vol->VolNode.Lock);
if( vol->Type->Cleanup )
vol->Type->Cleanup( vol->Ptr );
+ if( vol->CacheHandle )
+ IOCache_Destroy(vol->CacheHandle);
LOG("Removed volume %s", vol->Name);
free(vol);
}
// --------------------------------------------------------------------
// VFS Inteface
// --------------------------------------------------------------------
-char *LVM_Root_ReadDir(tVFS_Node *Node, int ID)
+int LVM_Root_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
{
tLVM_Vol *vol;
- if( ID < 0 ) return NULL;
+ if( ID < 0 ) return -EINVAL;
+
+ // TODO: Sub-dirs for 'by-uuid', 'by-label' etc
for( vol = gpLVM_FirstVolume; vol && ID --; vol = vol->Next );
- if(vol)
- return strdup(vol->Name);
+ if(vol) {
+ strncpy(Dest, vol->Name, FILENAME_MAX);
+ return 0;
+ }
else
- return NULL;
+ return -ENOENT;
}
-tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name)
+tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name, Uint Flags)
{
tLVM_Vol *vol;
for( vol = gpLVM_FirstVolume; vol; vol = vol->Next )
{
if( strcmp(vol->Name, Name) == 0 )
{
+ vol->DirNode.ReferenceCount ++;
return &vol->DirNode;
}
}
return NULL;
}
-char *LVM_Vol_ReadDir(tVFS_Node *Node, int ID)
+int LVM_Vol_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
{
tLVM_Vol *vol = Node->ImplPtr;
+ const char *src;
if( ID < 0 || ID >= vol->nSubVolumes+1 )
- return NULL;
+ return -EINVAL;
- if( ID == 0 )
- return strdup("ROOT");
- else
- return strdup( vol->SubVolumes[ID-1]->Name );
+ if( ID == 0 ) {
+ src = "ROOT";
+ }
+ else {
+ src = vol->SubVolumes[ID-1]->Name;
+ }
+ strncpy(Dest, src, FILENAME_MAX);
+ return 0;
}
-tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name)
+tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name, Uint Flags)
{
tLVM_Vol *vol = Node->ImplPtr;
{
if( strcmp(vol->SubVolumes[i]->Name, Name) == 0 )
{
+ vol->SubVolumes[i]->Node.ReferenceCount ++;
return &vol->SubVolumes[i]->Node;
}
}
return NULL;
}
-size_t LVM_Vol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
+size_t LVM_Vol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags)
{
tLVM_Vol *vol = Node->ImplPtr;
Uint64 byte_size = vol->BlockCount * vol->BlockSize;
);
}
-size_t LVM_Vol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)
+size_t LVM_Vol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags)
{
return 0;
}
-size_t LVM_SubVol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
+size_t LVM_SubVol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags)
{
tLVM_SubVolume *sv = Node->ImplPtr;
Uint64 byte_size = sv->BlockCount * sv->Vol->BlockSize;
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)
+size_t LVM_SubVol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags)
{
tLVM_SubVolume *sv = Node->ImplPtr;
Uint64 byte_size = sv->BlockCount * sv->Vol->BlockSize;
);
}
+void LVM_CloseNode(tVFS_Node *Node)
+{
+ Node->ReferenceCount --;
+}
+
Uint LVM_int_DrvUtil_ReadBlock(Uint64 Address, Uint Count, void *Buffer, void *Argument)
{
return LVM_int_ReadVolume( Argument, Address, Count, Buffer );