New upstream version 8.1.0

This commit is contained in:
geos_one
2025-08-10 01:34:16 +02:00
commit c891bb7105
4398 changed files with 838833 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
#include <common/toolkit/MathTk.h>
#include "BuddyMirrorPattern.h"
bool BuddyMirrorPattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx)
{
BuddyMirrorPattern* thisCast = (BuddyMirrorPattern*)this;
RawList mirrorBuddyGroupIDsVec;
// defaultNumTargets
if(!Serialization_deserializeUInt(ctx, &thisCast->defaultNumTargets) )
return false;
// mirrorBuddyGroupIDs
if(!Serialization_deserializeUInt16VecPreprocess(ctx, &mirrorBuddyGroupIDsVec) )
return false;
if(!Serialization_deserializeUInt16Vec(&mirrorBuddyGroupIDsVec, &thisCast->mirrorBuddyGroupIDs) )
return false;
// check mirrorBuddyGroupIDs
if(!UInt16Vec_length(&thisCast->mirrorBuddyGroupIDs) )
return false;
return true;
}
size_t BuddyMirrorPattern_getStripeTargetIndex(StripePattern* this, int64_t pos)
{
struct BuddyMirrorPattern* p = container_of(this, struct BuddyMirrorPattern, stripePattern);
return (pos / this->chunkSize) % UInt16Vec_length(&p->mirrorBuddyGroupIDs);
}
uint16_t BuddyMirrorPattern_getStripeTargetID(StripePattern* this, int64_t pos)
{
BuddyMirrorPattern* thisCast = (BuddyMirrorPattern*)this;
size_t targetIndex = BuddyMirrorPattern_getStripeTargetIndex(this, pos);
return UInt16Vec_at(&thisCast->mirrorBuddyGroupIDs, targetIndex);
}
void BuddyMirrorPattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs)
{
BuddyMirrorPattern* thisCast = (BuddyMirrorPattern*)this;
ListTk_copyUInt16ListToVec( (UInt16List*)&thisCast->mirrorBuddyGroupIDs, outTargetIDs);
}
UInt16Vec* BuddyMirrorPattern_getStripeTargetIDs(StripePattern* this)
{
BuddyMirrorPattern* thisCast = (BuddyMirrorPattern*)this;
return &thisCast->mirrorBuddyGroupIDs;
}
unsigned BuddyMirrorPattern_getMinNumTargets(StripePattern* this)
{
return 1;
}
unsigned BuddyMirrorPattern_getDefaultNumTargets(StripePattern* this)
{
BuddyMirrorPattern* thisCast = (BuddyMirrorPattern*)this;
return thisCast->defaultNumTargets;
}

View File

@@ -0,0 +1,124 @@
#ifndef BUDDYMIRRORPATTERN_H_
#define BUDDYMIRRORPATTERN_H_
#include <common/toolkit/Serialization.h>
#include "StripePattern.h"
struct BuddyMirrorPattern;
typedef struct BuddyMirrorPattern BuddyMirrorPattern;
static inline void BuddyMirrorPattern_init(BuddyMirrorPattern* this,
unsigned chunkSize, UInt16Vec* mirrorBuddyGroupIDs, unsigned defaultNumTargets);
static inline void BuddyMirrorPattern_initFromChunkSize(BuddyMirrorPattern* this,
unsigned chunkSize);
static inline BuddyMirrorPattern* BuddyMirrorPattern_construct(
unsigned chunkSize, UInt16Vec* mirrorBuddyGroupIDs, unsigned defaultNumTargets);
static inline BuddyMirrorPattern* BuddyMirrorPattern_constructFromChunkSize(unsigned chunkSize);
static inline void BuddyMirrorPattern_uninit(StripePattern* this);
static inline void __BuddyMirrorPattern_assignVirtualFunctions(BuddyMirrorPattern* this);
// virtual functions
extern bool BuddyMirrorPattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx);
extern size_t BuddyMirrorPattern_getStripeTargetIndex(StripePattern* this, int64_t pos);
extern uint16_t BuddyMirrorPattern_getStripeTargetID(StripePattern* this, int64_t pos);
extern void BuddyMirrorPattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs);
extern UInt16Vec* BuddyMirrorPattern_getStripeTargetIDs(StripePattern* this);
extern unsigned BuddyMirrorPattern_getMinNumTargets(StripePattern* this);
extern unsigned BuddyMirrorPattern_getDefaultNumTargets(StripePattern* this);
struct BuddyMirrorPattern
{
StripePattern stripePattern;
UInt16Vec mirrorBuddyGroupIDs;
unsigned defaultNumTargets;
};
/**
* @param mirrorBuddyGroupIDs will be copied
* @param defaultNumTargets default number of targets (0 for app-level default)
*/
void BuddyMirrorPattern_init(BuddyMirrorPattern* this,
unsigned chunkSize, UInt16Vec* mirrorBuddyGroupIDs, unsigned defaultNumTargets)
{
StripePattern_initFromPatternType( (StripePattern*)this, STRIPEPATTERN_BuddyMirror, chunkSize);
// assign virtual functions
__BuddyMirrorPattern_assignVirtualFunctions(this);
// init attribs
UInt16Vec_init(&this->mirrorBuddyGroupIDs);
ListTk_copyUInt16ListToVec( (UInt16List*)mirrorBuddyGroupIDs, &this->mirrorBuddyGroupIDs);
this->defaultNumTargets = defaultNumTargets ? defaultNumTargets : 4;
}
/**
* Note: for deserialization only
*/
void BuddyMirrorPattern_initFromChunkSize(BuddyMirrorPattern* this, unsigned chunkSize)
{
StripePattern_initFromPatternType( (StripePattern*)this, STRIPEPATTERN_BuddyMirror, chunkSize);
// assign virtual functions
__BuddyMirrorPattern_assignVirtualFunctions(this);
// init attribs
UInt16Vec_init(&this->mirrorBuddyGroupIDs);
}
/**
* @param mirrorBuddyGroupIDs will be copied
* @param defaultNumTargets default number of targets (0 for app-level default)
*/
BuddyMirrorPattern* BuddyMirrorPattern_construct(
unsigned chunkSize, UInt16Vec* mirrorBuddyGroupIDs, unsigned defaultNumTargets)
{
struct BuddyMirrorPattern* this = os_kmalloc(sizeof(*this) );
BuddyMirrorPattern_init(this, chunkSize, mirrorBuddyGroupIDs, defaultNumTargets);
return this;
}
/**
* Note: for deserialization only
*/
BuddyMirrorPattern* BuddyMirrorPattern_constructFromChunkSize(unsigned chunkSize)
{
struct BuddyMirrorPattern* this = os_kmalloc(sizeof(*this) );
BuddyMirrorPattern_initFromChunkSize(this, chunkSize);
return this;
}
void BuddyMirrorPattern_uninit(StripePattern* this)
{
BuddyMirrorPattern* thisCast = (BuddyMirrorPattern*)this;
UInt16Vec_uninit(&thisCast->mirrorBuddyGroupIDs);
}
void __BuddyMirrorPattern_assignVirtualFunctions(BuddyMirrorPattern* this)
{
( (StripePattern*)this)->uninit = BuddyMirrorPattern_uninit;
( (StripePattern*)this)->deserializePattern = BuddyMirrorPattern_deserializePattern;
( (StripePattern*)this)->getStripeTargetIndex = BuddyMirrorPattern_getStripeTargetIndex;
( (StripePattern*)this)->getStripeTargetID = BuddyMirrorPattern_getStripeTargetID;
( (StripePattern*)this)->getStripeTargetIDsCopy = BuddyMirrorPattern_getStripeTargetIDsCopy;
( (StripePattern*)this)->getStripeTargetIDs = BuddyMirrorPattern_getStripeTargetIDs;
( (StripePattern*)this)->getMinNumTargets = BuddyMirrorPattern_getMinNumTargets;
( (StripePattern*)this)->getDefaultNumTargets = BuddyMirrorPattern_getDefaultNumTargets;
}
#endif /*BUDDYMIRRORPATTERN_H_*/

View File

@@ -0,0 +1,70 @@
#include <common/toolkit/MathTk.h>
#include "Raid0Pattern.h"
bool Raid0Pattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx)
{
Raid0Pattern* thisCast = (Raid0Pattern*)this;
RawList targetIDsList;
// defaultNumTargets
if(!Serialization_deserializeUInt(ctx, &thisCast->defaultNumTargets) )
return false;
// targetIDs
if(!Serialization_deserializeUInt16VecPreprocess(ctx, &targetIDsList) )
return false;
if(!Serialization_deserializeUInt16Vec(&targetIDsList, &thisCast->stripeTargetIDs) )
return false;
// check targetIDs
if(!UInt16Vec_length(&thisCast->stripeTargetIDs) )
return false;
return true;
}
size_t Raid0Pattern_getStripeTargetIndex(StripePattern* this, int64_t pos)
{
struct Raid0Pattern* p = container_of(this, struct Raid0Pattern, stripePattern);
return (pos / this->chunkSize) % UInt16Vec_length(&p->stripeTargetIDs);
}
uint16_t Raid0Pattern_getStripeTargetID(StripePattern* this, int64_t pos)
{
Raid0Pattern* thisCast = (Raid0Pattern*)this;
size_t targetIndex = Raid0Pattern_getStripeTargetIndex(this, pos);
return UInt16Vec_at(&thisCast->stripeTargetIDs, targetIndex);
}
void Raid0Pattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs)
{
Raid0Pattern* thisCast = (Raid0Pattern*)this;
ListTk_copyUInt16ListToVec( (UInt16List*)&thisCast->stripeTargetIDs, outTargetIDs);
}
UInt16Vec* Raid0Pattern_getStripeTargetIDs(StripePattern* this)
{
Raid0Pattern* thisCast = (Raid0Pattern*)this;
return &thisCast->stripeTargetIDs;
}
unsigned Raid0Pattern_getMinNumTargets(StripePattern* this)
{
return 1;
}
unsigned Raid0Pattern_getDefaultNumTargets(StripePattern* this)
{
Raid0Pattern* thisCast = (Raid0Pattern*)this;
return thisCast->defaultNumTargets;
}

View File

@@ -0,0 +1,124 @@
#ifndef RAID0PATTERN_H_
#define RAID0PATTERN_H_
#include <common/toolkit/Serialization.h>
#include "StripePattern.h"
struct Raid0Pattern;
typedef struct Raid0Pattern Raid0Pattern;
static inline void Raid0Pattern_init(Raid0Pattern* this,
unsigned chunkSize, UInt16Vec* stripeTargetIDs, unsigned defaultNumTargets);
static inline void Raid0Pattern_initFromChunkSize(Raid0Pattern* this, unsigned chunkSize);
static inline Raid0Pattern* Raid0Pattern_construct(
unsigned chunkSize, UInt16Vec* stripeTargetIDs, unsigned defaultNumTargets);
static inline Raid0Pattern* Raid0Pattern_constructFromChunkSize(unsigned chunkSize);
static inline void Raid0Pattern_uninit(StripePattern* this);
static inline void __Raid0Pattern_assignVirtualFunctions(Raid0Pattern* this);
// virtual functions
extern bool Raid0Pattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx);
extern size_t Raid0Pattern_getStripeTargetIndex(StripePattern* this, int64_t pos);
extern uint16_t Raid0Pattern_getStripeTargetID(StripePattern* this, int64_t pos);
extern void Raid0Pattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs);
extern UInt16Vec* Raid0Pattern_getStripeTargetIDs(StripePattern* this);
extern unsigned Raid0Pattern_getMinNumTargets(StripePattern* this);
extern unsigned Raid0Pattern_getDefaultNumTargets(StripePattern* this);
struct Raid0Pattern
{
StripePattern stripePattern;
UInt16Vec stripeTargetIDs;
unsigned defaultNumTargets;
};
/**
* @param stripeTargetIDs will be copied
* @param defaultNumTargets default number of targets (0 for app-level default)
*/
void Raid0Pattern_init(Raid0Pattern* this,
unsigned chunkSize, UInt16Vec* stripeTargetIDs, unsigned defaultNumTargets)
{
StripePattern_initFromPatternType( (StripePattern*)this, STRIPEPATTERN_Raid0, chunkSize);
// assign virtual functions
__Raid0Pattern_assignVirtualFunctions(this);
// init attribs
UInt16Vec_init(&this->stripeTargetIDs);
ListTk_copyUInt16ListToVec( (UInt16List*)stripeTargetIDs, &this->stripeTargetIDs);
this->defaultNumTargets = defaultNumTargets ? defaultNumTargets : 4;
}
/**
* Note: for deserialization only
*/
void Raid0Pattern_initFromChunkSize(Raid0Pattern* this, unsigned chunkSize)
{
StripePattern_initFromPatternType( (StripePattern*)this, STRIPEPATTERN_Raid0, chunkSize);
// assign virtual functions
__Raid0Pattern_assignVirtualFunctions(this);
// init attribs
UInt16Vec_init(&this->stripeTargetIDs);
}
/**
* @param stripeTargetIDs will be copied
* @param defaultNumTargets default number of targets (0 for app-level default)
*/
Raid0Pattern* Raid0Pattern_construct(
unsigned chunkSize, UInt16Vec* stripeTargetIDs, unsigned defaultNumTargets)
{
struct Raid0Pattern* this = os_kmalloc(sizeof(*this) );
Raid0Pattern_init(this, chunkSize, stripeTargetIDs, defaultNumTargets);
return this;
}
/**
* Note: for deserialization only
*/
Raid0Pattern* Raid0Pattern_constructFromChunkSize(unsigned chunkSize)
{
struct Raid0Pattern* this = os_kmalloc(sizeof(*this) );
Raid0Pattern_initFromChunkSize(this, chunkSize);
return this;
}
void Raid0Pattern_uninit(StripePattern* this)
{
Raid0Pattern* thisCast = (Raid0Pattern*)this;
UInt16Vec_uninit(&thisCast->stripeTargetIDs);
}
void __Raid0Pattern_assignVirtualFunctions(Raid0Pattern* this)
{
( (StripePattern*)this)->uninit = Raid0Pattern_uninit;
( (StripePattern*)this)->deserializePattern = Raid0Pattern_deserializePattern;
( (StripePattern*)this)->getStripeTargetIndex = Raid0Pattern_getStripeTargetIndex;
( (StripePattern*)this)->getStripeTargetID = Raid0Pattern_getStripeTargetID;
( (StripePattern*)this)->getStripeTargetIDsCopy = Raid0Pattern_getStripeTargetIDsCopy;
( (StripePattern*)this)->getStripeTargetIDs = Raid0Pattern_getStripeTargetIDs;
( (StripePattern*)this)->getMinNumTargets = Raid0Pattern_getMinNumTargets;
( (StripePattern*)this)->getDefaultNumTargets = Raid0Pattern_getDefaultNumTargets;
}
#endif /*RAID0PATTERN_H_*/

View File

@@ -0,0 +1,113 @@
#include <common/toolkit/MathTk.h>
#include "Raid10Pattern.h"
bool Raid10Pattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx)
{
Raid10Pattern* thisCast = (Raid10Pattern*)this;
RawList targetIDsList;
RawList mirrorTargetIDsList;
// defaultNumTargets
if(!Serialization_deserializeUInt(ctx, &thisCast->defaultNumTargets) )
return false;
// targetIDs
if(!Serialization_deserializeUInt16VecPreprocess(ctx, &targetIDsList) )
return false;
if(!Serialization_deserializeUInt16Vec(&targetIDsList, &thisCast->stripeTargetIDs) )
return false;
// mirrorTargetIDs
if(!Serialization_deserializeUInt16VecPreprocess(ctx, &mirrorTargetIDsList) )
return false;
if(!Serialization_deserializeUInt16Vec(&mirrorTargetIDsList, &thisCast->mirrorTargetIDs) )
return false;
// calc stripeSetSize
thisCast->stripeSetSize = UInt16Vec_length(
&thisCast->stripeTargetIDs) * StripePattern_getChunkSize(this);
return true;
}
size_t Raid10Pattern_getStripeTargetIndex(StripePattern* this, int64_t pos)
{
Raid10Pattern* thisCast = (Raid10Pattern*)this;
/* the code below is an optimization (wrt division/modulo) of following the two lines:
int64_t stripeSetInnerOffset = pos % thisCast->stripeSetSize;
int64_t targetIndex = stripeSetInnerOffset / StripePattern_getChunkSize(this); */
// note: do_div(n64, base32) assigns the result to n64 and returns the remainder!
// (do_div is needed for 64bit division on 32bit archs)
unsigned stripeSetSize = thisCast->stripeSetSize;
int64_t stripeSetInnerOffset;
unsigned chunkSize;
size_t targetIndex;
if(MathTk_isPowerOfTwo(stripeSetSize) )
{ // quick path => no modulo needed
stripeSetInnerOffset = pos & (stripeSetSize - 1);
}
else
{ // slow path => modulo
stripeSetInnerOffset = do_div(pos, thisCast->stripeSetSize);
// warning: do_div modifies pos! (so do not use it afterwards within this method)
}
chunkSize = StripePattern_getChunkSize(this);
// this is "a=b/c" written as "a=b>>log2(c)", because chunkSize is a power of two.
targetIndex = (stripeSetInnerOffset >> MathTk_log2Int32(chunkSize) );
return targetIndex;
}
uint16_t Raid10Pattern_getStripeTargetID(StripePattern* this, int64_t pos)
{
Raid10Pattern* thisCast = (Raid10Pattern*)this;
size_t targetIndex = Raid10Pattern_getStripeTargetIndex(this, pos);
return UInt16Vec_at(&thisCast->stripeTargetIDs, targetIndex);
}
void Raid10Pattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs)
{
Raid10Pattern* thisCast = (Raid10Pattern*)this;
ListTk_copyUInt16ListToVec( (UInt16List*)&thisCast->stripeTargetIDs, outTargetIDs);
}
UInt16Vec* Raid10Pattern_getStripeTargetIDs(StripePattern* this)
{
Raid10Pattern* thisCast = (Raid10Pattern*)this;
return &thisCast->stripeTargetIDs;
}
UInt16Vec* Raid10Pattern_getMirrorTargetIDs(StripePattern* this)
{
Raid10Pattern* thisCast = (Raid10Pattern*)this;
return &thisCast->mirrorTargetIDs;
}
unsigned Raid10Pattern_getMinNumTargets(StripePattern* this)
{
return 2;
}
unsigned Raid10Pattern_getDefaultNumTargets(StripePattern* this)
{
Raid10Pattern* thisCast = (Raid10Pattern*)this;
return thisCast->defaultNumTargets;
}

View File

@@ -0,0 +1,96 @@
#ifndef RAID10PATTERN_H_
#define RAID10PATTERN_H_
#include <common/toolkit/Serialization.h>
#include "StripePattern.h"
struct Raid10Pattern;
typedef struct Raid10Pattern Raid10Pattern;
static inline void Raid10Pattern_initFromChunkSize(Raid10Pattern* this, unsigned chunkSize);
static inline Raid10Pattern* Raid10Pattern_constructFromChunkSize(unsigned chunkSize);
static inline void Raid10Pattern_uninit(StripePattern* this);
static inline void __Raid10Pattern_assignVirtualFunctions(Raid10Pattern* this);
// virtual functions
extern bool Raid10Pattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx);
extern size_t Raid10Pattern_getStripeTargetIndex(StripePattern* this, int64_t pos);
extern uint16_t Raid10Pattern_getStripeTargetID(StripePattern* this, int64_t pos);
extern void Raid10Pattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs);
extern UInt16Vec* Raid10Pattern_getStripeTargetIDs(StripePattern* this);
extern UInt16Vec* Raid10Pattern_getMirrorTargetIDs(StripePattern* this);
extern unsigned Raid10Pattern_getMinNumTargets(StripePattern* this);
extern unsigned Raid10Pattern_getDefaultNumTargets(StripePattern* this);
/**
* Note: We don't have the general _construct() and _init() methods implemented, because we just
* don't need them at the moment in the client. (We only have the special _constructFrom...() and
* _initFrom...() for deserialization.)
*/
struct Raid10Pattern
{
StripePattern stripePattern;
UInt16Vec stripeTargetIDs;
UInt16Vec mirrorTargetIDs;
unsigned stripeSetSize; // = numStripeTargets * chunkSize
unsigned defaultNumTargets;
};
/**
* Note: for deserialization only
*/
void Raid10Pattern_initFromChunkSize(Raid10Pattern* this, unsigned chunkSize)
{
StripePattern_initFromPatternType( (StripePattern*)this, STRIPEPATTERN_Raid10, chunkSize);
// assign virtual functions
__Raid10Pattern_assignVirtualFunctions(this);
// init attribs
UInt16Vec_init(&this->stripeTargetIDs);
UInt16Vec_init(&this->mirrorTargetIDs);
}
/**
* Note: for deserialization only
*/
Raid10Pattern* Raid10Pattern_constructFromChunkSize(unsigned chunkSize)
{
struct Raid10Pattern* this = os_kmalloc(sizeof(*this) );
Raid10Pattern_initFromChunkSize(this, chunkSize);
return this;
}
void Raid10Pattern_uninit(StripePattern* this)
{
Raid10Pattern* thisCast = (Raid10Pattern*)this;
UInt16Vec_uninit(&thisCast->stripeTargetIDs);
UInt16Vec_uninit(&thisCast->mirrorTargetIDs);
}
void __Raid10Pattern_assignVirtualFunctions(Raid10Pattern* this)
{
( (StripePattern*)this)->uninit = Raid10Pattern_uninit;
( (StripePattern*)this)->deserializePattern = Raid10Pattern_deserializePattern;
( (StripePattern*)this)->getStripeTargetIndex = Raid10Pattern_getStripeTargetIndex;
( (StripePattern*)this)->getStripeTargetID = Raid10Pattern_getStripeTargetID;
( (StripePattern*)this)->getStripeTargetIDsCopy = Raid10Pattern_getStripeTargetIDsCopy;
( (StripePattern*)this)->getStripeTargetIDs = Raid10Pattern_getStripeTargetIDs;
( (StripePattern*)this)->getMirrorTargetIDs = Raid10Pattern_getMirrorTargetIDs;
( (StripePattern*)this)->getMinNumTargets = Raid10Pattern_getMinNumTargets;
( (StripePattern*)this)->getDefaultNumTargets = Raid10Pattern_getDefaultNumTargets;
}
#endif /* RAID10PATTERN_H_ */

View File

@@ -0,0 +1,37 @@
#include "SimplePattern.h"
bool SimplePattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx)
{
return true;
}
size_t SimplePattern_getStripeTargetIndex(StripePattern* this, int64_t pos)
{
return 0;
}
uint16_t SimplePattern_getStripeTargetID(StripePattern* this, int64_t pos)
{
return 0;
}
unsigned SimplePattern_getMinNumTargets(StripePattern* this)
{
return 0;
}
unsigned SimplePattern_getDefaultNumTargets(StripePattern* this)
{
return 0;
}
void SimplePattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs)
{
// nothing to be done here
}
UInt16Vec* SimplePattern_getStripeTargetIDs(StripePattern* this)
{
return NULL;
}

View File

@@ -0,0 +1,65 @@
#ifndef SIMPLEPATTERN_H_
#define SIMPLEPATTERN_H_
#include "StripePattern.h"
struct SimplePattern;
typedef struct SimplePattern SimplePattern;
static inline void SimplePattern_init(SimplePattern* this,
unsigned patternType, unsigned chunkSize);
static inline SimplePattern* SimplePattern_construct(
unsigned patternType, unsigned chunkSize);
static inline void SimplePattern_uninit(StripePattern* this);
// virtual functions
extern bool SimplePattern_deserializePattern(StripePattern* this, DeserializeCtx* ctx);
extern size_t SimplePattern_getStripeTargetIndex(StripePattern* this, int64_t pos);
extern uint16_t SimplePattern_getStripeTargetID(StripePattern* this, int64_t pos);
extern unsigned SimplePattern_getMinNumTargets(StripePattern* this);
extern unsigned SimplePattern_getDefaultNumTargets(StripePattern* this);
extern void SimplePattern_getStripeTargetIDsCopy(StripePattern* this, UInt16Vec* outTargetIDs);
extern UInt16Vec* SimplePattern_getStripeTargetIDs(StripePattern* this);
struct SimplePattern
{
StripePattern stripePattern;
};
void SimplePattern_init(SimplePattern* this,
unsigned patternType, unsigned chunkSize)
{
StripePattern_initFromPatternType( (StripePattern*)this, patternType, chunkSize);
// assign virtual functions
( (StripePattern*)this)->uninit = SimplePattern_uninit;
( (StripePattern*)this)->deserializePattern = SimplePattern_deserializePattern;
( (StripePattern*)this)->getStripeTargetIndex = SimplePattern_getStripeTargetIndex;
( (StripePattern*)this)->getStripeTargetID = SimplePattern_getStripeTargetID;
( (StripePattern*)this)->getStripeTargetIDsCopy = SimplePattern_getStripeTargetIDsCopy;
( (StripePattern*)this)->getStripeTargetIDs = SimplePattern_getStripeTargetIDs;
( (StripePattern*)this)->getMinNumTargets = SimplePattern_getMinNumTargets;
( (StripePattern*)this)->getDefaultNumTargets = SimplePattern_getDefaultNumTargets;
}
SimplePattern* SimplePattern_construct(unsigned patternType, unsigned chunkSize)
{
struct SimplePattern* this = os_kmalloc(sizeof(struct SimplePattern) );
SimplePattern_init(this, patternType, chunkSize);
return this;
}
void SimplePattern_uninit(StripePattern* this)
{
}
#endif /*SIMPLEPATTERN_H_*/

View File

@@ -0,0 +1,139 @@
#include <common/toolkit/Serialization.h>
#include "BuddyMirrorPattern.h"
#include "Raid0Pattern.h"
#include "Raid10Pattern.h"
#include "SimplePattern.h"
#include "StripePattern.h"
#define HAS_NO_POOL_FLAG (1 << 24)
/**
* Calls the virtual uninit method and kfrees the object.
*/
void StripePattern_virtualDestruct(StripePattern* this)
{
this->uninit(this);
kfree(this);
}
bool StripePattern_deserializePatternPreprocess(DeserializeCtx* ctx,
const char** outPatternStart, uint32_t* outPatternLength)
{
DeserializeCtx temp = *ctx;
if(!Serialization_deserializeUInt(&temp, outPatternLength))
return false;
*outPatternStart = ctx->data;
if (*outPatternLength > ctx->length)
return false;
ctx->data += *outPatternLength;
ctx->length -= *outPatternLength;
return true;
}
/**
* @return outPattern; outPattern->patternType is STRIPEPATTERN_Invalid on error
*/
StripePattern* StripePattern_createFromBuf(const char* patternStart,
uint32_t patternLength)
{
struct StripePatternHeader patternHeader;
StripePattern* pattern;
DeserializeCtx ctx = {
.data = patternStart,
.length = patternLength,
};
bool deserRes;
if (!__StripePattern_deserializeHeader(&ctx, &patternHeader))
return (StripePattern*)SimplePattern_construct(STRIPEPATTERN_Invalid, 0);
switch (patternHeader.patternType)
{
case STRIPEPATTERN_Raid0:
{
pattern = (StripePattern*)Raid0Pattern_constructFromChunkSize(patternHeader.chunkSize);
} break;
case STRIPEPATTERN_Raid10:
{
pattern = (StripePattern*)Raid10Pattern_constructFromChunkSize(patternHeader.chunkSize);
} break;
case STRIPEPATTERN_BuddyMirror:
{
pattern = (StripePattern*)BuddyMirrorPattern_constructFromChunkSize(
patternHeader.chunkSize);
} break;
default:
{
pattern = (StripePattern*)SimplePattern_construct(STRIPEPATTERN_Invalid, 0);
return pattern;
} break;
}
deserRes = pattern->deserializePattern(pattern, &ctx);
if(unlikely(!deserRes) )
{ // deserialization failed => discard half-initialized pattern and create new invalid pattern
StripePattern_virtualDestruct(pattern);
pattern = (StripePattern*)SimplePattern_construct(STRIPEPATTERN_Invalid, 0);
return pattern;
}
return pattern;
}
bool __StripePattern_deserializeHeader(DeserializeCtx* ctx,
struct StripePatternHeader* outPatternHeader)
{
// pattern length
if(!Serialization_deserializeUInt(ctx, &outPatternHeader->patternLength) )
return false;
// pattern type
if(!Serialization_deserializeUInt(ctx, &outPatternHeader->patternType) )
return false;
// chunkSize
if(!Serialization_deserializeUInt(ctx, &outPatternHeader->chunkSize) )
return false;
// storagePoolId
if (!(outPatternHeader->patternType & HAS_NO_POOL_FLAG)) {
if(!StoragePoolId_deserialize(ctx, &outPatternHeader->storagePoolId) )
return false;
}
outPatternHeader->patternType &= ~HAS_NO_POOL_FLAG;
// check length field
if(outPatternHeader->patternLength < STRIPEPATTERN_HEADER_LENGTH)
return false;
// check chunkSize
if(!outPatternHeader->chunkSize)
return false;
return true;
}
/**
* Predefined virtual method returning NULL. Will be overridden by StripePatterns (e.g. Raid10)
* that actually do have mirror targets.
*
* @return NULL for patterns that don't have mirror targets.
*/
UInt16Vec* StripePattern_getMirrorTargetIDs(StripePattern* this)
{
return NULL;
}

View File

@@ -0,0 +1,146 @@
#ifndef STRIPEPATTERN_H_
#define STRIPEPATTERN_H_
/**
* Note: Do not instantiate this "class" directly (it contains pure virtual functions)
*/
#include <common/Common.h>
#include <common/storage/StoragePoolId.h>
#include <common/toolkit/SerializationTypes.h>
#include <common/toolkit/vector/UInt16Vec.h>
// pattern types
#define STRIPEPATTERN_Invalid 0
#define STRIPEPATTERN_Raid0 1
#define STRIPEPATTERN_Raid10 2
#define STRIPEPATTERN_BuddyMirror 3
// minimum allowed stripe pattern chunk size (in bytes)
#define STRIPEPATTERN_MIN_CHUNKSIZE (1024*64)
// pattern serialization defs
#define STRIPEPATTERN_HEADER_LENGTH \
(sizeof(unsigned) + sizeof(unsigned) + sizeof(unsigned))
/* length + type + chunkSize*/
struct StripePatternHeader
{
// everything in this struct is in host byte order!
unsigned patternLength; // in bytes
unsigned patternType; // the type of pattern, defined as STRIPEPATTERN_x
unsigned chunkSize;
// storagePoolId is unused in the client at the moment; however we deserialize it to avoid human
// errors later
StoragePoolId storagePoolId;
};
struct StripePattern;
typedef struct StripePattern StripePattern;
static inline void StripePattern_initFromPatternType(StripePattern* this,
unsigned patternType, unsigned chunkSize);
extern void StripePattern_virtualDestruct(struct StripePattern* this);
extern bool StripePattern_deserializePatternPreprocess(DeserializeCtx* ctx,
const char** outPatternStart, uint32_t* outPatternLength);
extern bool __StripePattern_deserializeHeader(DeserializeCtx* ctx,
struct StripePatternHeader* outPatternHeader);
// static functions
extern StripePattern* StripePattern_createFromBuf(const char* patternStart,
uint32_t patternLength);
// virtual functions
extern UInt16Vec* StripePattern_getMirrorTargetIDs(StripePattern* this);
// getters & setters
static inline int StripePattern_getPatternType(StripePattern* this);
static inline unsigned StripePattern_getChunkSize(StripePattern* this);
static inline int64_t StripePattern_getChunkStart(StripePattern* this, int64_t pos);
static inline int64_t StripePattern_getNextChunkStart(StripePattern* this, int64_t pos);
static inline int64_t StripePattern_getChunkEnd(StripePattern* this, int64_t pos);
struct StripePattern
{
unsigned patternType; // STRIPEPATTERN_...
unsigned chunkSize; // must be a power of two (optimizations rely on it)
unsigned serialPatternLength; // for (de)serialization
// virtual functions
void (*uninit) (StripePattern* this);
// (de)serialization
bool (*deserializePattern) (StripePattern* this, DeserializeCtx* ctx);
size_t (*getStripeTargetIndex) (StripePattern* this, int64_t pos);
uint16_t (*getStripeTargetID) (StripePattern* this, int64_t pos);
void (*getStripeTargetIDsCopy) (StripePattern* this, UInt16Vec* outTargetIDs);
UInt16Vec* (*getStripeTargetIDs) (StripePattern* this);
UInt16Vec* (*getMirrorTargetIDs) (StripePattern* this);
unsigned (*getMinNumTargets) (StripePattern* this);
unsigned (*getDefaultNumTargets) (StripePattern* this);
};
void StripePattern_initFromPatternType(StripePattern* this, unsigned patternType,
unsigned chunkSize)
{
this->patternType = patternType;
this->chunkSize = chunkSize;
this->serialPatternLength = 0;
// pre-defined virtual methods
this->getMirrorTargetIDs = StripePattern_getMirrorTargetIDs;
}
int StripePattern_getPatternType(StripePattern* this)
{
return this->patternType;
}
unsigned StripePattern_getChunkSize(StripePattern* this)
{
return this->chunkSize;
}
int64_t StripePattern_getChunkStart(StripePattern* this, int64_t pos)
{
// the code below is an optimization (wrt division) for the following line:
// int64_t chunkStart = pos - (pos % this->chunkSize);
// "& chunkSize -1" instead of "%", because chunkSize is a power of two
unsigned posModChunkSize = pos & (this->chunkSize - 1);
int64_t chunkStart = pos - posModChunkSize;
return chunkStart;
}
/**
* Get the exact file position where the next chunk starts
*/
int64_t StripePattern_getNextChunkStart(StripePattern* this, int64_t pos)
{
return StripePattern_getChunkStart(this, pos) + this->chunkSize;
}
/**
* Get the exact file position where the current chunk ends
*/
int64_t StripePattern_getChunkEnd(StripePattern* this, int64_t pos)
{
return StripePattern_getNextChunkStart(this, pos) - 1;
}
#endif /*STRIPEPATTERN_H_*/