Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F4293587
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
11 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/trunk/libxmount_morphing/libxmount_morphing_raid/libxmount_morphing_raid.c b/trunk/libxmount_morphing/libxmount_morphing_raid/libxmount_morphing_raid.c
index 37f7884..718af0c 100644
--- a/trunk/libxmount_morphing/libxmount_morphing_raid/libxmount_morphing_raid.c
+++ b/trunk/libxmount_morphing/libxmount_morphing_raid/libxmount_morphing_raid.c
@@ -1,374 +1,374 @@
/*******************************************************************************
* xmount Copyright (c) 2008-2017 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../libxmount_morphing.h"
#include "libxmount_morphing_raid.h"
#define LOG_DEBUG(...) { \
LIBXMOUNT_LOG_DEBUG(p_raid_handle->debug,__VA_ARGS__); \
}
/*******************************************************************************
* LibXmount_Morphing API implementation
******************************************************************************/
/*
* LibXmount_Morphing_GetApiVersion
*/
uint8_t LibXmount_Morphing_GetApiVersion() {
return LIBXMOUNT_MORPHING_API_VERSION;
}
/*
* LibXmount_Morphing_GetSupportedFormats
*/
const char* LibXmount_Morphing_GetSupportedTypes() {
return "raid0\0\0";
}
/*
* LibXmount_Morphing_GetFunctions
*/
void LibXmount_Morphing_GetFunctions(ts_LibXmountMorphingFunctions *p_functions)
{
p_functions->CreateHandle=&RaidCreateHandle;
p_functions->DestroyHandle=&RaidDestroyHandle;
p_functions->Morph=&RaidMorph;
p_functions->Size=&RaidSize;
p_functions->Read=&RaidRead;
p_functions->OptionsHelp=&RaidOptionsHelp;
p_functions->OptionsParse=&RaidOptionsParse;
p_functions->GetInfofileContent=&RaidGetInfofileContent;
p_functions->GetErrorMessage=&RaidGetErrorMessage;
p_functions->FreeBuffer=&RaidFreeBuffer;
}
/*******************************************************************************
* Private
******************************************************************************/
/*
* RaidCreateHandle
*/
static int RaidCreateHandle(void **pp_handle,
const char *p_format,
uint8_t debug)
{
pts_RaidHandle p_raid_handle;
// Alloc new handle
p_raid_handle=malloc(sizeof(ts_RaidHandle));
if(p_raid_handle==NULL) return RAID_MEMALLOC_FAILED;
// Init handle values
p_raid_handle->debug=debug;
p_raid_handle->input_images_count=0;
p_raid_handle->chunk_size=RAID_DEFAULT_CHUNKSIZE;
p_raid_handle->chunks_per_image=0;
p_raid_handle->p_input_functions=NULL;
p_raid_handle->morphed_image_size=0;
LOG_DEBUG("Created new LibXmount_Morphing_Raid handle\n");
// Return new handle
*pp_handle=p_raid_handle;
return RAID_OK;
}
/*
* RaidDestroyHandle
*/
static int RaidDestroyHandle(void **pp_handle) {
pts_RaidHandle p_raid_handle=(pts_RaidHandle)*pp_handle;
LOG_DEBUG("Destroying LibXmount_Morphing_Raid handle\n");
// Free handle
free(p_raid_handle);
*pp_handle=NULL;
return RAID_OK;
}
/*
* RaidMorph
*/
static int RaidMorph(void *p_handle,
pts_LibXmountMorphingInputFunctions p_input_functions)
{
pts_RaidHandle p_raid_handle=(pts_RaidHandle)p_handle;
int ret;
uint64_t input_image_size;
uint64_t chunks_per_image;
LOG_DEBUG("Initializing LibXmount_Morphing_Raid\n");
// Set input functions and get image count
p_raid_handle->p_input_functions=p_input_functions;
if(p_raid_handle->
p_input_functions->
ImageCount(&p_raid_handle->input_images_count)!=0)
{
return RAID_CANNOT_GET_IMAGECOUNT;
}
// Calculate chunks per image
for(uint64_t i=0;i<p_raid_handle->input_images_count;i++) {
ret=p_raid_handle->
p_input_functions->
Size(i,&input_image_size);
if(ret!=0) return RAID_CANNOT_GET_IMAGESIZE;
chunks_per_image=input_image_size/p_raid_handle->chunk_size;
LOG_DEBUG("Image %" PRIu64 " can hold a maximum of %" PRIu64 " chunks of %"
PRIu32 " bytes\n",
i,
chunks_per_image,
p_raid_handle->chunk_size);
// The smallest image determines how many chunks are availbale on all images
if(p_raid_handle->chunks_per_image==0) {
p_raid_handle->chunks_per_image=chunks_per_image;
} else if(chunks_per_image<p_raid_handle->chunks_per_image) {
p_raid_handle->chunks_per_image=chunks_per_image;
}
}
LOG_DEBUG("Smallest image holds %" PRIu64 " chunks of %" PRIu32 " bytes\n",
p_raid_handle->chunks_per_image,
p_raid_handle->chunk_size);
// Calculate total raid capacity based on smallest disk
p_raid_handle->morphed_image_size=
p_raid_handle->chunks_per_image*
p_raid_handle->chunk_size*p_raid_handle->input_images_count;
LOG_DEBUG("Total raid capacity is %" PRIu64 " bytes\n",
p_raid_handle->morphed_image_size);
return RAID_OK;
}
/*
* RaidSize
*/
static int RaidSize(void *p_handle, uint64_t *p_size) {
*p_size=((pts_RaidHandle)(p_handle))->morphed_image_size;
return RAID_OK;
}
/*
* RaidRead
*/
static int RaidRead(void *p_handle,
char *p_buf,
off_t offset,
size_t count,
size_t *p_read)
{
pts_RaidHandle p_raid_handle=(pts_RaidHandle)p_handle;
uint64_t cur_chunk;
uint64_t cur_image;
off_t cur_chunk_offset;
off_t cur_image_offset;
size_t cur_count;
int ret;
size_t read;
LOG_DEBUG("Reading %zu bytes at offset %zu from morphed image\n",
count,
offset);
// Make sure read parameters are within morphed image bounds
if(offset>=p_raid_handle->morphed_image_size ||
offset+count>p_raid_handle->morphed_image_size)
{
return RAID_READ_BEYOND_END_OF_IMAGE;
}
// Calculate starting chunk, and chunk offset
cur_chunk=offset/p_raid_handle->chunk_size;
cur_chunk_offset=offset-(cur_chunk*p_raid_handle->chunk_size);
// Init p_read
*p_read=0;
while(count!=0) {
// Calculate image and image offset to read from
cur_image=cur_chunk%p_raid_handle->input_images_count;
cur_image_offset=
(cur_chunk/p_raid_handle->input_images_count)*p_raid_handle->chunk_size;
// Calculate how many bytes to read from current chunk
if(cur_chunk_offset+count>p_raid_handle->chunk_size) {
cur_count=p_raid_handle->chunk_size-cur_chunk_offset;
} else {
cur_count=count;
}
LOG_DEBUG("Reading %zu bytes at offset %zu from image %" PRIu64
" (chunk %" PRIu64 ")\n",
cur_count,
cur_image_offset+cur_chunk_offset,
cur_image,
cur_chunk);
// Read bytes
ret=p_raid_handle->p_input_functions->
Read(cur_image,
p_buf,
cur_image_offset+cur_chunk_offset,
cur_count,
&read);
if(ret!=0 || read!=cur_count) return RAID_CANNOT_READ_DATA;
p_buf+=cur_count;
cur_chunk_offset=0;
count-=cur_count;
cur_chunk++;
(*p_read)+=cur_count;
}
return RAID_OK;
}
/*
* RaidOptionsHelp
*/
static int RaidOptionsHelp(const char **pp_help) {
int ok;
char *p_buf;
ok=asprintf(&p_buf,
" raid_chunksize : Specify the chunk size to use in bytes. "
"Defaults to 524288 (512k).\n");
if(ok<0 || p_buf==NULL) {
*pp_help=NULL;
return RAID_MEMALLOC_FAILED;
}
*pp_help=p_buf;
return RAID_OK;
}
/*
* RaidOptionsParse
*/
static int RaidOptionsParse(void *p_handle,
uint32_t options_count,
const pts_LibXmountOptions *pp_options,
const char **pp_error)
{
pts_RaidHandle p_raid_handle=(pts_RaidHandle)p_handle;
int ok;
uint32_t uint32value;
char *p_buf;
for(uint32_t i=0;i<options_count;i++) {
- if(strcmp(pp_options[i]->p_key,"raid_chunksize")) {
+ if(strcmp(pp_options[i]->p_key,"raid_chunksize")==0) {
// Convert value to uint32
uint32value=StrToUint32(pp_options[i]->p_value,&ok);
if(ok==0 || uint32value==0) {
// Conversion failed, generate error message and return
ok=asprintf(&p_buf,
"Unable to parse value '%s' of '%s' as valid 32bit number",
pp_options[i]->p_value,
pp_options[i]->p_key);
if(ok<0 || *pp_error==NULL) {
*pp_error=NULL;
return RAID_MEMALLOC_FAILED;
}
*pp_error=p_buf;
return RAID_CANNOT_PARSE_OPTION;
}
LOG_DEBUG("Setting chunk size to %" PRIu32 " bytes\n",uint32value);
// Conversion ok, save value and mark option as valid
p_raid_handle->chunk_size=uint32value;
pp_options[i]->valid=1;
continue;
}
}
return RAID_OK;
}
/*
* RaidGetInfofileContent
*/
static int RaidGetInfofileContent(void *p_handle,
const char **pp_info_buf)
{
pts_RaidHandle p_raid_handle=(pts_RaidHandle)p_handle;
int ret;
char *p_buf;
ret=asprintf(&p_buf,
"Simulating RAID level 0 over %" PRIu64 " disks.\n"
"Chunk size: %" PRIu32 " bytes\n"
"Chunks per disk: %" PRIu64 "\n"
"Total capacity: %" PRIu64 " bytes (%0.3f GiB)\n",
p_raid_handle->input_images_count,
p_raid_handle->chunk_size,
p_raid_handle->chunks_per_image,
p_raid_handle->morphed_image_size,
p_raid_handle->morphed_image_size/(1024.0*1024.0*1024.0));
if(ret<0 || *pp_info_buf==NULL) return RAID_MEMALLOC_FAILED;
*pp_info_buf=p_buf;
return RAID_OK;
}
/*
* RaidGetErrorMessage
*/
static const char* RaidGetErrorMessage(int err_num) {
switch(err_num) {
case RAID_MEMALLOC_FAILED:
return "Unable to allocate memory";
break;
case RAID_CANNOT_GET_IMAGECOUNT:
return "Unable to get input image count";
break;
case RAID_CANNOT_GET_IMAGESIZE:
return "Unable to get input image size";
break;
case RAID_READ_BEYOND_END_OF_IMAGE:
return "Unable to read data: Attempt to read past EOF";
break;
case RAID_CANNOT_READ_DATA:
return "Unable to read data";
break;
case RAID_CANNOT_PARSE_OPTION:
return "Unable to parse library option";
break;
default:
return "Unknown error";
}
}
/*
* RaidFreeBuffer
*/
static void RaidFreeBuffer(void *p_buf) {
free(p_buf);
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 23, 6:19 PM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1163016
Default Alt Text
(11 KB)
Attached To
Mode
rXMOUNT xmount
Attached
Detach File
Event Timeline
Log In to Comment