2 * Acess2 Logical Volume Manager
3 * - By John Hodge (thePowersGang)
11 int LVM_int_VFSReadEmul(void *Arg, Uint64 BlockStart, size_t BlockCount, void *Dest);
12 int LVM_int_VFSWriteEmul(void *Arg, Uint64 BlockStart, size_t BlockCount, const void *Source);
15 // --------------------------------------------------------------------
16 // Managment / Initialisation
17 // --------------------------------------------------------------------
18 int LVM_AddVolumeVFS(const char *Name, int FD)
20 // Assuming 512-byte blocks, not a good idea
21 return LVM_AddVolume(Name, (void*)(Uint)FD, 512, LVM_int_VFSReadEmul, LVM_int_VFSWriteEmul);
24 int LVM_AddVolume(const char *Name, void *Ptr, size_t BlockSize, tLVM_ReadFcn Read, tLVM_WriteFcn Write)
32 dummy_vol.Read = Read;
33 dummy_vol.Write = Write;
34 dummy_vol.BlockSize = BlockSize;
36 // Read the first block of the volume
37 first_block = malloc(BlockSize);
38 Read(Ptr, 0, 1, first_block);
41 // TODO: Determine type
44 // Type->CountSubvolumes
45 dummy_vol.nSubVolumes = type->CountSubvolumes(&dummy_vol, first_block);
47 // Create real volume descriptor
48 // TODO: If this needs to be rescanned later, having the subvolume list separate might be an idea
49 real_vol = malloc( sizeof(tLVM_Vol) + strlen(Name) + 1 + sizeof(tLVM_SubVolume*) * dummy_vol.nSubVolumes );
51 real_vol->Read = Read;
52 real_vol->Write = Write;
53 real_vol->BlockSize = BlockSize;
54 real_vol->nSubVolumes = dummy_vol.nSubVolumes;
55 real_vol->SubVolumes = (void*)( real_vol->Name + strlen(Name) + 1 );
56 strcpy(real_vol->Name, Name);
57 memset(real_vol->SubVolumes, 0, sizeof(tLVM_SubVolume*) * real_vol->nSubVolumes);
59 memset(&real_vol->DirNode, 0, sizeof(tVFS_Node));
60 real_vol->DirNode.Type = &gLVM_VolNodeType;
61 real_vol->DirNode.ImplPtr = real_vol;
62 real_vol->DirNode.Flags = VFS_FFLAG_DIRECTORY;
63 memset(&real_vol->VolNode, 0, sizeof(tVFS_Node));
64 real_vol->VolNode.Type = &gLVM_VolNodeType;
65 real_vol->VolNode.ImplPtr = real_vol;
66 real_vol->VolNode.Flags = VFS_FFLAG_DIRECTORY;
68 // Type->PopulateSubvolumes
69 type->PopulateSubvolumes(real_vol, first_block);
73 gpLVM_LastVolume->Next = real_vol;
74 gpLVM_LastVolume = real_vol;
79 void LVM_int_SetSubvolume_Anon(tLVM_Vol *Volume, int Index, Uint64 FirstBlock, Uint64 BlockCount)
84 if( Index < 0 || Index >= Volume->nSubVolumes ) {
85 Log_Warning("LVM", "SV ID is out of range (0 < %i < %i)",
86 Index, Volume->nSubVolumes);
90 if( Volume->SubVolumes[Index] ) {
91 Log_Warning("LVM", "Attempt to set SV %i of %p twice", Index, Volume);
95 namelen = snprintf(NULL, 0, "%i", Index);
97 sv = malloc( sizeof(tLVM_SubVolume) + namelen + 1 );
102 Volume->SubVolumes[Index] = sv;
105 sprintf(sv->Name, "%i", Index);
106 sv->FirstBlock = FirstBlock;
107 sv->BlockCount = BlockCount;
108 memset(&sv->Node, 0, sizeof(tVFS_Node));
110 sv->Node.ImplPtr = sv;
111 sv->Node.Type = &gLVM_SubVolNodeType;
114 // --------------------------------------------------------------------
116 // --------------------------------------------------------------------
117 size_t LVM_int_ReadVolume(tLVM_Vol *Volume, Uint64 BlockNum, size_t BlockCount, void *Dest)
119 return Volume->Read(Volume->Ptr, BlockNum, BlockCount, Dest);
122 size_t LVM_int_WriteVolume(tLVM_Vol *Volume, Uint64 BlockNum, size_t BlockCount, const void *Src)
124 return Volume->Write(Volume->Ptr, BlockNum, BlockCount, Src);
127 int LVM_int_VFSReadEmul(void *Arg, Uint64 BlockStart, size_t BlockCount, void *Dest)
132 blocksize = 512; // TODO: Don't assume
134 rv = VFS_ReadAt( (int)(Uint)Arg, BlockStart * blocksize, BlockCount * blocksize, Dest );
139 int LVM_int_VFSWriteEmul(void *Arg, Uint64 BlockStart, size_t BlockCount, const void *Source)
144 blocksize = 512; // TODO: Don't assume
146 rv = VFS_WriteAt( (int)(Uint)Arg, BlockStart * blocksize, BlockCount * blocksize, Source );