New upstream version 8.1.0
This commit is contained in:
1693
client_module/source/net/filesystem/FhgfsOpsCommKit.c
Normal file
1693
client_module/source/net/filesystem/FhgfsOpsCommKit.c
Normal file
File diff suppressed because it is too large
Load Diff
146
client_module/source/net/filesystem/FhgfsOpsCommKit.h
Normal file
146
client_module/source/net/filesystem/FhgfsOpsCommKit.h
Normal file
@@ -0,0 +1,146 @@
|
||||
#ifndef FHGFSOPSCOMMKIT_H_
|
||||
#define FHGFSOPSCOMMKIT_H_
|
||||
|
||||
#include <common/storage/PathInfo.h>
|
||||
#ifdef BEEGFS_NVFS
|
||||
#include <common/storage/RdmaInfo.h>
|
||||
#endif
|
||||
#include <os/iov_iter.h>
|
||||
#include "FhgfsOpsCommKitCommon.h"
|
||||
|
||||
struct FileOpState;
|
||||
typedef struct FileOpState FileOpState;
|
||||
|
||||
struct FsyncContext;
|
||||
|
||||
|
||||
bool FhgfsOpsCommKit_initEmergencyPools(void);
|
||||
void FhgfsOpsCommKit_releaseEmergencyPools(void);
|
||||
|
||||
|
||||
extern void FhgfsOpsCommkit_communicate(App* app, RemotingIOInfo* ioInfo,
|
||||
struct list_head* targetInfos, const struct CommKitContextOps* ops, void* private);
|
||||
|
||||
|
||||
extern void FhgfsOpsCommKit_readfileV2bCommunicate(App* app, RemotingIOInfo* ioInfo,
|
||||
struct list_head* states, void (*nextIter)(CommKitContext*, FileOpState*),
|
||||
void (*prepare)(CommKitContext*, FileOpState*));
|
||||
|
||||
extern void FhgfsOpsCommKit_writefileV2bCommunicate(App* app, RemotingIOInfo* ioInfo,
|
||||
struct list_head* states, void (*nextIter)(CommKitContext*, FileOpState*),
|
||||
void (*prepare)(CommKitContext*, FileOpState*));
|
||||
|
||||
extern void FhgfsOpsCommKit_fsyncCommunicate(App* app, RemotingIOInfo* ioInfo,
|
||||
struct FsyncContext* context);
|
||||
|
||||
extern void FhgfsOpsCommKit_statStorageCommunicate(App* app, struct list_head* targets);
|
||||
|
||||
|
||||
|
||||
extern void FhgfsOpsCommKit_initFileOpState(FileOpState* state, loff_t offset, size_t size,
|
||||
uint16_t targetID);
|
||||
|
||||
|
||||
enum CommKitState
|
||||
{
|
||||
CommKitState_PREPARE,
|
||||
CommKitState_SENDHEADER,
|
||||
CommKitState_SENDDATA,
|
||||
CommKitState_RECVHEADER,
|
||||
CommKitState_RECVDATA,
|
||||
CommKitState_SOCKETINVALIDATE,
|
||||
CommKitState_CLEANUP,
|
||||
CommKitState_RETRYWAIT,
|
||||
CommKitState_DONE,
|
||||
};
|
||||
|
||||
struct CommKitTargetInfo
|
||||
{
|
||||
struct list_head targetInfoList;
|
||||
|
||||
// (set to _PREPARE in the beginning, assigned by the state-creator)
|
||||
enum CommKitState state; // the current stage of the individual communication process
|
||||
|
||||
// used by GenericResponse handler
|
||||
struct {
|
||||
unsigned peerTryAgain:1;
|
||||
unsigned indirectCommError:1;
|
||||
unsigned indirectCommErrorNoRetry:1;
|
||||
} logged;
|
||||
|
||||
// assigned by the state-creator
|
||||
char* headerBuffer; // for serialization
|
||||
uint16_t targetID;
|
||||
uint16_t selectedTargetID; // either targetID or the buddy, if useBuddyMirrorSecond
|
||||
bool useBuddyMirrorSecond; // if buddy mirroring, this msg goes to secondary
|
||||
|
||||
// set by _PREPARE handler
|
||||
Node* node; // target-node reference
|
||||
Socket* socket; // target-node connection
|
||||
unsigned headerSize;
|
||||
|
||||
// error if negative, other set by specialized actions
|
||||
int64_t nodeResult;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct FileOpState
|
||||
{
|
||||
struct CommKitTargetInfo base;
|
||||
|
||||
// data for spefic modes (will be assigned by the corresponding modes)
|
||||
size_t transmitted; // how much data has been transmitted already
|
||||
size_t toBeTransmitted; // how much data has to be transmitted
|
||||
size_t totalSize; // how much data was requested
|
||||
|
||||
// data for all modes
|
||||
|
||||
// (assigned by the state-creator)
|
||||
struct iov_iter data;
|
||||
loff_t offset; // target-node local offset
|
||||
|
||||
bool firstWriteDoneForTarget; /* true if a chunk was previously written to this target in
|
||||
this session; used for the session check */
|
||||
bool receiveFileData; /* if false, receive the int64 fragment length, else the fragment */
|
||||
|
||||
// result data
|
||||
int64_t expectedNodeResult; // the amount of data that we wanted to read
|
||||
#ifdef BEEGFS_NVFS
|
||||
RdmaInfo* rdmap;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct FsyncContext {
|
||||
unsigned userID;
|
||||
bool forceRemoteFlush;
|
||||
bool checkSession;
|
||||
bool doSyncOnClose;
|
||||
|
||||
struct list_head states;
|
||||
};
|
||||
|
||||
struct FsyncState {
|
||||
struct CommKitTargetInfo base;
|
||||
|
||||
bool firstWriteDoneForTarget;
|
||||
};
|
||||
|
||||
extern void FhgfsOpsCommKit_initFsyncState(struct FsyncContext* context, struct FsyncState* state,
|
||||
uint16_t targetID);
|
||||
|
||||
|
||||
|
||||
struct StatStorageState
|
||||
{
|
||||
struct CommKitTargetInfo base;
|
||||
|
||||
int64_t totalSize;
|
||||
int64_t totalFree;
|
||||
};
|
||||
|
||||
extern void FhgfsOpsCommKit_initStatStorageState(struct list_head* states,
|
||||
struct StatStorageState* state, uint16_t targetID);
|
||||
|
||||
#endif /*FHGFSOPSCOMMKIT_H_*/
|
||||
187
client_module/source/net/filesystem/FhgfsOpsCommKitCommon.h
Normal file
187
client_module/source/net/filesystem/FhgfsOpsCommKitCommon.h
Normal file
@@ -0,0 +1,187 @@
|
||||
#ifndef FHGFSOPSCOMMKITCOMMON_H_
|
||||
#define FHGFSOPSCOMMKITCOMMON_H_
|
||||
|
||||
#include <app/log/Logger.h>
|
||||
#include <common/net/message/session/rw/WriteLocalFileRespMsg.h>
|
||||
#include <common/toolkit/MessagingTk.h>
|
||||
#include <common/toolkit/SocketTk.h>
|
||||
#include <common/Common.h>
|
||||
#include <common/Types.h>
|
||||
#include <net/filesystem/RemotingIOInfo.h>
|
||||
#include <nodes/NodeStoreEx.h>
|
||||
|
||||
|
||||
#define BEEGFS_COMMKIT_MSGBUF_SIZE 4096
|
||||
|
||||
#define COMMKIT_DEBUG_READ_SEND (1 << 0)
|
||||
#define COMMKIT_DEBUG_READ_HEADER (1 << 1)
|
||||
#define COMMKIT_DEBUG_RECV_DATA (1 << 2)
|
||||
#define COMMKIT_DEBUG_WRITE_HEADER (1 << 3)
|
||||
#define COMMKIT_DEBUG_WRITE_POLL (1 << 4)
|
||||
#define COMMKIT_DEBUG_WRITE_SEND (1 << 5)
|
||||
#define COMMKIT_DEBUG_WRITE_RECV (1 << 6)
|
||||
|
||||
// #define BEEGFS_COMMKIT_DEBUG 0b010
|
||||
|
||||
#ifndef BEEGFS_COMMKIT_DEBUG
|
||||
#define BEEGFS_COMMKIT_DEBUG 0
|
||||
#endif
|
||||
|
||||
#ifdef BEEGFS_COMMKIT_DEBUG
|
||||
#define CommKitErrorInjectRate 101 // fail a send/receive req every X jiffies
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
struct CommKitContext;
|
||||
typedef struct CommKitContext CommKitContext;
|
||||
|
||||
|
||||
|
||||
static inline void __FhgfsOpsCommKitCommon_pollStateSocks(CommKitContext* context,
|
||||
size_t numStates);
|
||||
static inline void __FhgfsOpsCommKitCommon_handlePollError(CommKitContext* context,
|
||||
int pollRes);
|
||||
|
||||
|
||||
struct CommKitTargetInfo;
|
||||
|
||||
enum
|
||||
{
|
||||
CK_RETRY_BUDDY_FALLBACK = 1 << 0,
|
||||
CK_RETRY_LOOP_EAGAIN = 1 << 1,
|
||||
};
|
||||
|
||||
enum CKTargetBadAction
|
||||
{
|
||||
CK_SKIP_TARGET = 0,
|
||||
CK_CONTINUE_TARGET = 1,
|
||||
};
|
||||
|
||||
|
||||
struct CommKitContextOps
|
||||
{
|
||||
enum CKTargetBadAction (*selectedTargetBad)(CommKitContext*, struct CommKitTargetInfo*,
|
||||
const CombinedTargetState*);
|
||||
|
||||
unsigned (*prepareHeader)(CommKitContext*, struct CommKitTargetInfo*);
|
||||
|
||||
// returns >0 for successful send, 0 to advance to next state, or negative error code
|
||||
int (*sendData)(CommKitContext*, struct CommKitTargetInfo*);
|
||||
|
||||
// return >= for success, 0 to advance, or negative beegfs error code
|
||||
int (*recvHeader)(CommKitContext*, struct CommKitTargetInfo*);
|
||||
// return >= for success, 0 to advance, or negative beegfs error code
|
||||
int (*recvData)(CommKitContext*, struct CommKitTargetInfo*);
|
||||
|
||||
void (*printSendDataDetails)(CommKitContext*, struct CommKitTargetInfo*);
|
||||
void (*printSocketDetails)(CommKitContext*, struct CommKitTargetInfo*);
|
||||
|
||||
int retryFlags;
|
||||
const char* logContext;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Additional data that is required or useful for all the states.
|
||||
* (This is shared states data.)
|
||||
*
|
||||
* invariant: (numRetryWaiters + numDone + numUnconnectable + numPollSocks) <= numStates
|
||||
*/
|
||||
struct CommKitContext
|
||||
{
|
||||
const struct CommKitContextOps* ops;
|
||||
|
||||
App* app;
|
||||
Logger* log;
|
||||
void* private;
|
||||
|
||||
RemotingIOInfo* ioInfo;
|
||||
|
||||
struct list_head* targetInfoList;
|
||||
|
||||
unsigned numRetryWaiters; // number of states with a communication error
|
||||
unsigned numDone; // number of finished states
|
||||
|
||||
unsigned numAcquiredConns; // number of acquired conns to decide waiting or not (avoids deadlock)
|
||||
unsigned numUnconnectable; // states that didn't get a conn this round (reset to 0 in each round)
|
||||
unsigned numBufferless; // states that couldn't acquire a header buffer
|
||||
|
||||
bool pollTimedOut;
|
||||
bool pollTimeoutLogged;
|
||||
bool connFailedLogged;
|
||||
|
||||
PollState pollState;
|
||||
unsigned numPollSocks;
|
||||
|
||||
unsigned currentRetryNum; // number of used up retries (in case of comm errors)
|
||||
unsigned maxNumRetries; // 0 if infinite number of retries enabled
|
||||
#ifdef BEEGFS_NVFS
|
||||
int gpudRc;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Poll the state socks that need to be polled.
|
||||
* This will call _handlePollError() if something goes wrong with the poll(), e.g. timeout.
|
||||
*
|
||||
* Note: Caller must have checked that there actually are socks that need polling
|
||||
* (context.numPollSocks>0) before calling this.
|
||||
*/
|
||||
void __FhgfsOpsCommKitCommon_pollStateSocks(CommKitContext* context, size_t numStates)
|
||||
{
|
||||
int pollRes;
|
||||
|
||||
Config* cfg = App_getConfig(context->app);
|
||||
|
||||
size_t numWaiters = context->numPollSocks + context->numRetryWaiters +
|
||||
context->numDone + context->numUnconnectable + context->numBufferless;
|
||||
|
||||
/* if not all the states are polling or done, some states must be ready to do something
|
||||
immediately => set timeout to 0 (non-blocking) */
|
||||
/* note: be very careful with timeoutMS==0, because that means we don't release the CPU,
|
||||
so we need to ensure that timeoutMS==0 is no permanent condition. */
|
||||
int timeoutMS = (numWaiters < numStates) ? 0 : cfg->connMsgLongTimeout;
|
||||
BEEGFS_BUG_ON_DEBUG(numWaiters > numStates, "numWaiters > numStates should never happen");
|
||||
|
||||
pollRes = SocketTk_poll(&context->pollState, timeoutMS);
|
||||
if(unlikely( (timeoutMS && pollRes <= 0) || (pollRes < 0) ) )
|
||||
__FhgfsOpsCommKitCommon_handlePollError(context, pollRes);
|
||||
}
|
||||
|
||||
void __FhgfsOpsCommKitCommon_handlePollError(CommKitContext* context, int pollRes)
|
||||
{
|
||||
// note: notifies the waiting sockets via context.pollTimedOut (they do not care whether
|
||||
// it was a timeout or an error)
|
||||
|
||||
if(!context->pollTimeoutLogged)
|
||||
{
|
||||
if(!pollRes)
|
||||
{ // no incoming data => timout or interrupted
|
||||
if (fatal_signal_pending(current))
|
||||
{ // interrupted
|
||||
Logger_logFormatted(context->log, 3, context->ops->logContext,
|
||||
"Communication (poll() ) interrupted by signal.");
|
||||
}
|
||||
else
|
||||
{ // timout
|
||||
Logger_logErrFormatted(context->log, context->ops->logContext,
|
||||
"Communication (poll() ) timeout for %u sockets.", context->numPollSocks);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // error
|
||||
Logger_logErrFormatted(context->log, context->ops->logContext,
|
||||
"Communication (poll() ) error for %u sockets. ErrCode: %d",
|
||||
context->numPollSocks, pollRes);
|
||||
}
|
||||
}
|
||||
|
||||
context->pollTimeoutLogged = true;
|
||||
context->pollTimedOut = true;
|
||||
}
|
||||
|
||||
|
||||
#endif /*FHGFSOPSCOMMKITCOMMON_H_*/
|
||||
1193
client_module/source/net/filesystem/FhgfsOpsCommKitVec.c
Normal file
1193
client_module/source/net/filesystem/FhgfsOpsCommKitVec.c
Normal file
File diff suppressed because it is too large
Load Diff
156
client_module/source/net/filesystem/FhgfsOpsCommKitVec.h
Normal file
156
client_module/source/net/filesystem/FhgfsOpsCommKitVec.h
Normal file
@@ -0,0 +1,156 @@
|
||||
#ifndef FHGFSOPSCOMMKITVEC_H_
|
||||
#define FHGFSOPSCOMMKITVEC_H_
|
||||
|
||||
#include <net/filesystem/FhgfsOpsRemoting.h>
|
||||
#include <toolkit/FhgfsPage.h>
|
||||
#include <toolkit/FhgfsChunkPageVec.h>
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
#include "FhgfsOpsCommKitCommon.h"
|
||||
#include "RemotingIOInfo.h"
|
||||
|
||||
|
||||
struct FhgfsCommKitVec;
|
||||
typedef struct FhgfsCommKitVec FhgfsCommKitVec;
|
||||
|
||||
struct CommKitVecHelper;
|
||||
typedef struct CommKitVecHelper CommKitVecHelper;
|
||||
|
||||
|
||||
extern int64_t FhgfsOpsCommKitVec_rwFileCommunicate(App* app, RemotingIOInfo* ioInfo,
|
||||
FhgfsCommKitVec* comm, Fhgfs_RWType rwType);
|
||||
|
||||
|
||||
static inline FhgfsCommKitVec FhgfsOpsCommKitVec_assignRWfileState(FhgfsChunkPageVec* pageVec,
|
||||
unsigned pageIdx, unsigned numPages, loff_t offset, uint16_t targetID, char* msgBuf);
|
||||
|
||||
static inline void FhgfsOpsCommKitVec_setRWFileStateFirstWriteDone(
|
||||
bool firstWriteDoneForTarget, FhgfsCommKitVec* outComm);
|
||||
|
||||
static inline size_t FhgfsOpsCommKitVec_getRemainingDataSize(FhgfsCommKitVec* comm);
|
||||
static inline loff_t FhgfsOpsCommKitVec_getOffset(FhgfsCommKitVec* comm);
|
||||
|
||||
|
||||
|
||||
struct FhgfsCommKitVec
|
||||
{
|
||||
// Depending if we are going to read or write, the corresponding struct will be used
|
||||
union
|
||||
{
|
||||
// NOTE: The *initial* stage for read and write MUST be RW_FILE_STAGE_PREPARE
|
||||
struct readState
|
||||
{
|
||||
size_t reqLen; // requested size from client to server
|
||||
size_t serverSize; // how many data the server is going to send (<= reqLen)
|
||||
} read ;
|
||||
|
||||
struct writeState
|
||||
{
|
||||
WriteLocalFileRespMsg respMsg; // response message
|
||||
} write;
|
||||
};
|
||||
|
||||
size_t hdrLen; // size (length) of the header message
|
||||
|
||||
size_t numSuccessPages; // number of pages successfully handled
|
||||
|
||||
// data for all stages
|
||||
|
||||
// (assigned by the state-creator)
|
||||
FhgfsChunkPageVec* pageVec;
|
||||
loff_t initialOffset; // initial offset before sending any data
|
||||
|
||||
uint16_t targetID; // target ID
|
||||
char* msgBuf; // for serialization
|
||||
|
||||
bool firstWriteDoneForTarget; /* true if data was previously written to this target in
|
||||
this session; used for the session check */
|
||||
bool useBuddyMirrorSecond; // for buddy mirroring, this msg goes to secondary
|
||||
bool useServersideMirroring; // data shall be forwarded to mirror by primary
|
||||
|
||||
// (assigned by the preparation stage)
|
||||
Node* node; // target-node reference
|
||||
Socket* sock; // target-node connection
|
||||
|
||||
// result information
|
||||
int64_t nodeResult; /* the amount of data that have been read/written on the server side
|
||||
* (or a negative fhgfs error code) */
|
||||
|
||||
bool doHeader; // continue with the read/write header stage
|
||||
};
|
||||
|
||||
/**
|
||||
* Additional data that is required or useful for all the states.
|
||||
* (This is shared states data.)
|
||||
*
|
||||
* invariant: (numRetryWaiters + isDone + numUnconnectable + numPollSocks) <= numStates
|
||||
*/
|
||||
struct CommKitVecHelper
|
||||
{
|
||||
App* app;
|
||||
Logger* log;
|
||||
char* logContext;
|
||||
|
||||
RemotingIOInfo* ioInfo;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Note: Caller still MUST initialize type.{read/write}.stage = RW_FILE_STAGE_PREPARE.
|
||||
* Note: Initializes the expectedNodeResult attribute from the size argument.
|
||||
* Note: Defaults to server-side mirroring.
|
||||
*/
|
||||
FhgfsCommKitVec FhgfsOpsCommKitVec_assignRWfileState(FhgfsChunkPageVec* pageVec,
|
||||
unsigned pageIdx, unsigned numPages, loff_t offset, uint16_t targetID, char* msgBuf)
|
||||
{
|
||||
FhgfsCommKitVec state =
|
||||
{
|
||||
.initialOffset = offset,
|
||||
.targetID = targetID,
|
||||
.msgBuf = msgBuf,
|
||||
|
||||
.firstWriteDoneForTarget = false, // set via separate setter method
|
||||
.useBuddyMirrorSecond = false, // set via separate setter method
|
||||
.useServersideMirroring = true, // set via separate setter method
|
||||
|
||||
.nodeResult = -FhgfsOpsErr_INTERNAL,
|
||||
.numSuccessPages = 0,
|
||||
};
|
||||
|
||||
state.pageVec = pageVec;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void FhgfsOpsCommKitVec_setRWFileStateFirstWriteDone(bool firstWriteDoneForTarget,
|
||||
FhgfsCommKitVec* outComm)
|
||||
{
|
||||
outComm->firstWriteDoneForTarget = firstWriteDoneForTarget;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the overall remaining data size (chunkPageVec + last incompletely processed page)
|
||||
*/
|
||||
size_t FhgfsOpsCommKitVec_getRemainingDataSize(FhgfsCommKitVec* comm)
|
||||
{
|
||||
return FhgfsChunkPageVec_getRemainingDataSize(comm->pageVec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current offset
|
||||
*/
|
||||
loff_t FhgfsOpsCommKitVec_getOffset(FhgfsCommKitVec* comm)
|
||||
{
|
||||
FhgfsChunkPageVec* pageVec = comm->pageVec;
|
||||
|
||||
// data size already send/received (written/read)
|
||||
size_t processedSize =
|
||||
FhgfsChunkPageVec_getDataSize(pageVec) - FhgfsOpsCommKitVec_getRemainingDataSize(comm);
|
||||
|
||||
return comm->initialOffset + processedSize;
|
||||
}
|
||||
|
||||
|
||||
#endif /*FHGFSOPSCOMMKITVEC_H_*/
|
||||
2617
client_module/source/net/filesystem/FhgfsOpsRemoting.c
Normal file
2617
client_module/source/net/filesystem/FhgfsOpsRemoting.c
Normal file
File diff suppressed because it is too large
Load Diff
174
client_module/source/net/filesystem/FhgfsOpsRemoting.h
Normal file
174
client_module/source/net/filesystem/FhgfsOpsRemoting.h
Normal file
@@ -0,0 +1,174 @@
|
||||
#ifndef FHGFSOPSREMOTING_H_
|
||||
#define FHGFSOPSREMOTING_H_
|
||||
|
||||
#include <common/Common.h>
|
||||
#include <filesystem/FsObjectInfo.h>
|
||||
#include <filesystem/FsDirInfo.h>
|
||||
#include <filesystem/FsFileInfo.h>
|
||||
#include <common/storage/StorageDefinitions.h>
|
||||
#include <common/toolkit/MetadataTk.h>
|
||||
#include <common/storage/FileEvent.h>
|
||||
#include <common/storage/StorageErrors.h>
|
||||
#include <net/filesystem/FhgfsOpsCommKit.h>
|
||||
#include <net/filesystem/RemotingIOInfo.h>
|
||||
#include <os/iov_iter.h>
|
||||
#include <toolkit/FhgfsPage.h>
|
||||
#include <toolkit/FhgfsChunkPageVec.h>
|
||||
|
||||
enum Fhgfs_RWType;
|
||||
typedef enum Fhgfs_RWType Fhgfs_RWType;
|
||||
|
||||
struct FileOpVecState {
|
||||
FileOpState base;
|
||||
|
||||
struct iov_iter data;
|
||||
};
|
||||
|
||||
union RWFileVecState {
|
||||
struct FileOpVecState read;
|
||||
struct FileOpState write;
|
||||
};
|
||||
|
||||
|
||||
struct StripePattern; // forward declaration
|
||||
struct NetMessage; // forward declaration
|
||||
|
||||
extern bool FhgfsOpsRemoting_initMsgBufCache(void);
|
||||
extern void FhgfsOpsRemoting_destroyMsgBufCache(void);
|
||||
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_listdirFromOffset(const EntryInfo* entryInfo,
|
||||
FsDirInfo* dirInfo, unsigned maxOutNames);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_statRoot(App* app, fhgfs_stat* outFhgfsStat);
|
||||
static inline FhgfsOpsErr FhgfsOpsRemoting_statDirect(App* app, const EntryInfo* entryInfo,
|
||||
fhgfs_stat* outFhgfsStat);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_statDirect(App* app, const EntryInfo* entryInfo,
|
||||
fhgfs_stat* outFhgfsStat);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_statAndGetParentInfo(App* app, const EntryInfo* entryInfo,
|
||||
fhgfs_stat* outFhgfsStat, NumNodeID* outParentNodeID, char** outParentEntryID);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_setAttr(App* app, const EntryInfo* entryInfo,
|
||||
SettableFileAttribs* fhgfsAttr, int validAttribs, const struct FileEvent* event);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_mkdir(App* app, const EntryInfo* parentInfo,
|
||||
struct CreateInfo* createInfo, EntryInfo* outEntryInfo);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_rmdir(App* app, const EntryInfo* parentInfo,
|
||||
const char* entryName, const struct FileEvent* event);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_mkfile(App* app, const EntryInfo* parentInfo,
|
||||
struct CreateInfo* createInfo, EntryInfo* outEntryInfo);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_mkfileWithStripeHints(App* app, const EntryInfo* parentInfo,
|
||||
struct CreateInfo* createInfo, unsigned numtargets, unsigned chunksize, EntryInfo* outEntryInfo);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_unlinkfile(App* app, const EntryInfo* parentInfo,
|
||||
const char* entryName, const struct FileEvent* event);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_openfile(const EntryInfo* entryInfo, RemotingIOInfo* ioInfo,
|
||||
uint32_t* outVersion, const struct FileEvent* event);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_closefile(const EntryInfo* entryInfo,
|
||||
RemotingIOInfo* ioInfo, const struct FileEvent* event);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_closefileEx(const EntryInfo* entryInfo,
|
||||
RemotingIOInfo* ioInfo, bool allowRetries, const struct FileEvent* event);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_flockAppendEx(const EntryInfo* entryInfo, RWLock* eiRLock,
|
||||
App* app, const char* fileHandleID, int64_t clientFD, int ownerPID, int lockTypeFlags,
|
||||
bool allowRetries);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_flockEntryEx(const EntryInfo* entryInfo, RWLock* eiRLock,
|
||||
App* app, const char* fileHandleID, int64_t clientFD, int ownerPID, int lockTypeFlags,
|
||||
bool allowRetries);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_flockRangeEx(const EntryInfo* entryInfo, RWLock* eiRLock,
|
||||
App* app, const char* fileHandleID, int ownerPID, int lockTypeFlags, uint64_t start, uint64_t end,
|
||||
bool allowRetries);
|
||||
|
||||
extern ssize_t FhgfsOpsRemoting_writefileVec(struct iov_iter* iter, loff_t offset,
|
||||
RemotingIOInfo* ioInfo, bool serializeWrites);
|
||||
|
||||
static inline ssize_t FhgfsOpsRemoting_writefile(const char __user *buf, size_t size, loff_t offset,
|
||||
RemotingIOInfo* ioInfo)
|
||||
{
|
||||
struct iov_iter *iter = STACK_ALLOC_BEEGFS_ITER_IOV(buf, size, WRITE);
|
||||
return FhgfsOpsRemoting_writefileVec(iter, offset, ioInfo, false);
|
||||
}
|
||||
|
||||
static inline ssize_t FhgfsOpsRemoting_writefile_kernel(const char *buf, size_t size, loff_t offset,
|
||||
RemotingIOInfo* ioInfo)
|
||||
{
|
||||
struct iov_iter *iter = STACK_ALLOC_BEEGFS_ITER_KVEC(buf, size, WRITE);
|
||||
return FhgfsOpsRemoting_writefileVec(iter, offset, ioInfo, false);
|
||||
}
|
||||
|
||||
extern ssize_t FhgfsOpsRemoting_rwChunkPageVec(FhgfsChunkPageVec *pageVec, RemotingIOInfo* ioInfo,
|
||||
Fhgfs_RWType rwType);
|
||||
extern ssize_t FhgfsOpsRemoting_readfileVec(struct iov_iter *iter, size_t size, loff_t offset,
|
||||
RemotingIOInfo* ioInfo, FhgfsInode* fhgfsInode);
|
||||
|
||||
static inline ssize_t FhgfsOpsRemoting_readfile_user(char __user *buf, size_t size, loff_t offset,
|
||||
RemotingIOInfo* ioInfo, FhgfsInode* fhgfsInode)
|
||||
{
|
||||
struct iov_iter *iter = STACK_ALLOC_BEEGFS_ITER_IOV(buf, size, READ);
|
||||
return FhgfsOpsRemoting_readfileVec(iter, size, offset, ioInfo, fhgfsInode);
|
||||
}
|
||||
|
||||
static inline ssize_t FhgfsOpsRemoting_readfile_kernel(char *buf, size_t size, loff_t offset,
|
||||
RemotingIOInfo* ioInfo, FhgfsInode* fhgfsInode)
|
||||
{
|
||||
struct iov_iter *iter = STACK_ALLOC_BEEGFS_ITER_KVEC(buf, size, READ);
|
||||
return FhgfsOpsRemoting_readfileVec(iter, size, offset, ioInfo, fhgfsInode);
|
||||
}
|
||||
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_rename(App* app, const char* oldName, unsigned oldLen,
|
||||
DirEntryType entryType, const EntryInfo* fromDirInfo, const char* newName, unsigned newLen,
|
||||
const EntryInfo* toDirInfo, const struct FileEvent* event);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_truncfile(App* app, const EntryInfo* entryInfo, loff_t size,
|
||||
const struct FileEvent* event);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_fsyncfile(RemotingIOInfo* ioInfo, bool forceRemoteFlush,
|
||||
bool checkSession, bool doSyncOnClose);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_statStoragePath(App* app, bool ignoreErrors,
|
||||
int64_t* outSizeTotal, int64_t* outSizeFree);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_listXAttr(App* app, const EntryInfo* entryInfo, char* value,
|
||||
size_t size, ssize_t* outSize);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_getXAttr(App* app, const EntryInfo* entryInfo, const char* name,
|
||||
void* value, size_t size, ssize_t* outSize);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_removeXAttr(App* app, const EntryInfo* entryInfo,
|
||||
const char* name);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_setXAttr(App* app, const EntryInfo* entryInfo, const char* name,
|
||||
const char* value, const size_t size, int flags);
|
||||
|
||||
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_lookupIntent(App* app,
|
||||
const LookupIntentInfoIn* inInfo, LookupIntentInfoOut* outInfo);
|
||||
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_hardlink(App* app, const char* fromName, unsigned fromLen,
|
||||
const EntryInfo* fromInfo, const EntryInfo* fromDirInfo, const char* toName, unsigned toLen,
|
||||
const EntryInfo* toDirInfo, const struct FileEvent* event);
|
||||
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_refreshEntry(App* app, const EntryInfo* entryInfo);
|
||||
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_bumpFileVersion(App* app, const EntryInfo* entryInfo,
|
||||
bool persistent, const struct FileEvent* event);
|
||||
extern FhgfsOpsErr FhgfsOpsRemoting_getFileVersion(App* app, const EntryInfo* entryInfo,
|
||||
uint32_t* outVersion);
|
||||
|
||||
FhgfsOpsErr __FhgfsOpsRemoting_flockGenericEx(struct NetMessage* requestMsg, unsigned respMsgType,
|
||||
NodeOrGroup owner, bool isBuddyMirrored, App* app, const char* fileHandleID, int lockTypeFlags,
|
||||
char* lockAckID, bool allowRetries, RWLock* eiRLock);
|
||||
|
||||
#ifdef LOG_DEBUG_MESSAGES
|
||||
extern void __FhgfsOpsRemoting_logDebugIOCall(const char* logContext, size_t size, loff_t offset,
|
||||
RemotingIOInfo* ioInfo, const char* rwTypeStr);
|
||||
#else
|
||||
#define __FhgfsOpsRemoting_logDebugIOCall(logContext, size, offset, ioInfo, rwTypeStr)
|
||||
#endif // LOG_DEBUG_MESSAGES
|
||||
|
||||
|
||||
enum Fhgfs_RWType
|
||||
{
|
||||
BEEGFS_RWTYPE_READ = 0, // read request
|
||||
BEEGFS_RWTYPE_WRITE // write request
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stat a file or directory using EntryInfo.
|
||||
*/
|
||||
FhgfsOpsErr FhgfsOpsRemoting_statDirect(App* app, const EntryInfo* entryInfo,
|
||||
fhgfs_stat* outFhgfsStat)
|
||||
{
|
||||
return FhgfsOpsRemoting_statAndGetParentInfo(app, entryInfo, outFhgfsStat, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
#endif /*FHGFSOPSREMOTING_H_*/
|
||||
144
client_module/source/net/filesystem/RemotingIOInfo.h
Normal file
144
client_module/source/net/filesystem/RemotingIOInfo.h
Normal file
@@ -0,0 +1,144 @@
|
||||
#ifndef REMOTINGIOINFO_H_
|
||||
#define REMOTINGIOINFO_H_
|
||||
|
||||
#include <common/Common.h>
|
||||
#include <common/storage/PathInfo.h>
|
||||
#include <common/storage/striping/StripePattern.h>
|
||||
#include <toolkit/BitStore.h>
|
||||
#include <app/App.h>
|
||||
|
||||
|
||||
struct RemotingIOInfo;
|
||||
typedef struct RemotingIOInfo RemotingIOInfo;
|
||||
|
||||
|
||||
|
||||
// inliners
|
||||
static inline void RemotingIOInfo_initOpen(App* app, unsigned accessFlags,
|
||||
AtomicInt* pMaxUsedTargetIndex, PathInfo* pathInfo, RemotingIOInfo* outIOInfo);
|
||||
static inline void RemotingIOInfo_initSpecialClose(App* app, const char* fileHandleID,
|
||||
AtomicInt* maxUsedTargetIndex, unsigned accessFlags, RemotingIOInfo* outIOInfo);
|
||||
static inline void RemotingIOInfo_freeVals(RemotingIOInfo* outIOInfo);
|
||||
static inline size_t RemotingIOInfo_getNumPagesPerStripe(RemotingIOInfo* ioInfo);
|
||||
static inline size_t RemotingIOInfo_getNumPagesPerChunk(RemotingIOInfo* ioInfo);
|
||||
|
||||
|
||||
|
||||
struct RemotingIOInfo
|
||||
{
|
||||
App* app;
|
||||
|
||||
const char* fileHandleID;
|
||||
struct StripePattern* pattern;
|
||||
PathInfo* pathInfo;
|
||||
unsigned accessFlags; // OPENFILE_ACCESS_... flags
|
||||
|
||||
// pointers to fhgfsInode->fileHandles[handleType]...
|
||||
|
||||
bool* needsAppendLockCleanup; // (note: can be NULL in some cases, implies "false")
|
||||
AtomicInt* maxUsedTargetIndex;
|
||||
BitStore* firstWriteDone;
|
||||
|
||||
unsigned userID; // only used in storage server write message
|
||||
unsigned groupID; // only used in storage server write message
|
||||
#ifdef BEEGFS_NVFS
|
||||
bool nvfs;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Prepares a RemotingIOInfo for Remoting_openfile().
|
||||
*
|
||||
* Note: Be careful with this. This is only useful in very special cases (e.g. stateless file IO,
|
||||
* when you call FhgfsOpsRemoting_openfile() directly). Some values like userID also need to be
|
||||
* set manually in these cases.
|
||||
* You will typically rather go through the inode and thus use FhgfsInode_referenceHandle().
|
||||
*
|
||||
* @param accessFlags OPENFILE_ACCESS_... flags
|
||||
* @param maxUsedTargetIndex may be NULL for open, but in case you will use the ioInfo also for
|
||||
* IO, you will probably want to set it.
|
||||
*/
|
||||
void RemotingIOInfo_initOpen(App* app, unsigned accessFlags, AtomicInt* maxUsedTargetIndex,
|
||||
PathInfo* pathInfo, RemotingIOInfo* outIOInfo)
|
||||
{
|
||||
outIOInfo->app = app;
|
||||
|
||||
outIOInfo->fileHandleID = NULL;
|
||||
outIOInfo->pattern = NULL;
|
||||
outIOInfo->pathInfo = pathInfo;
|
||||
outIOInfo->accessFlags = accessFlags;
|
||||
|
||||
outIOInfo->needsAppendLockCleanup = NULL;
|
||||
outIOInfo->maxUsedTargetIndex = maxUsedTargetIndex;
|
||||
outIOInfo->firstWriteDone = NULL;
|
||||
|
||||
outIOInfo->userID = 0;
|
||||
outIOInfo->groupID = 0;
|
||||
#ifdef BEEGFS_NVFS
|
||||
outIOInfo->nvfs = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize RemotingIOInfo for close only. This is used for very special failures in
|
||||
* atomic_open and lookup_open.
|
||||
*/
|
||||
void RemotingIOInfo_initSpecialClose(App* app, const char* fileHandleID,
|
||||
AtomicInt* maxUsedTargetIndex, unsigned accessFlags, RemotingIOInfo* outIOInfo)
|
||||
{
|
||||
outIOInfo->app = app;
|
||||
|
||||
outIOInfo->fileHandleID = fileHandleID;
|
||||
outIOInfo->pattern = NULL;
|
||||
outIOInfo->pathInfo = NULL;
|
||||
outIOInfo->accessFlags = accessFlags;
|
||||
|
||||
outIOInfo->needsAppendLockCleanup = NULL;
|
||||
outIOInfo->maxUsedTargetIndex = maxUsedTargetIndex;
|
||||
outIOInfo->firstWriteDone = NULL;
|
||||
|
||||
outIOInfo->userID = 0;
|
||||
outIOInfo->groupID = 0;
|
||||
#ifdef BEEGFS_NVFS
|
||||
outIOInfo->nvfs = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: Be careful with this. This is only useful in very special cases (e.g. stateless file IO,
|
||||
* when you called Remoting_openfile() directly). You will typically rather use the
|
||||
* FhgfsInode_referenceHandle() & Co routines.
|
||||
*/
|
||||
void RemotingIOInfo_freeVals(RemotingIOInfo* outIOInfo)
|
||||
{
|
||||
SAFE_DESTRUCT(outIOInfo->pattern, StripePattern_virtualDestruct);
|
||||
SAFE_KFREE(outIOInfo->fileHandleID);
|
||||
|
||||
if (outIOInfo->pathInfo)
|
||||
PathInfo_uninit(outIOInfo->pathInfo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the number of pages per stripe
|
||||
*/
|
||||
size_t RemotingIOInfo_getNumPagesPerStripe(RemotingIOInfo* ioInfo)
|
||||
{
|
||||
StripePattern* pattern = ioInfo->pattern;
|
||||
UInt16Vec* targetIDs = pattern->getStripeTargetIDs(pattern);
|
||||
size_t numStripeNodes = UInt16Vec_length(targetIDs);
|
||||
|
||||
return RemotingIOInfo_getNumPagesPerChunk(ioInfo) * numStripeNodes;
|
||||
}
|
||||
|
||||
size_t RemotingIOInfo_getNumPagesPerChunk(RemotingIOInfo* ioInfo)
|
||||
{
|
||||
StripePattern* pattern = ioInfo->pattern;
|
||||
unsigned chunkSize = StripePattern_getChunkSize(pattern);
|
||||
|
||||
return chunkSize / PAGE_SIZE;
|
||||
}
|
||||
|
||||
#endif /* REMOTINGIOINFO_H_ */
|
||||
223
client_module/source/net/message/NetMessageFactory.c
Normal file
223
client_module/source/net/message/NetMessageFactory.c
Normal file
@@ -0,0 +1,223 @@
|
||||
// control messages
|
||||
#include <common/net/message/control/AckMsgEx.h>
|
||||
#include <common/net/message/control/GenericResponseMsg.h>
|
||||
// nodes messages
|
||||
#include <common/net/message/nodes/GetNodesRespMsg.h>
|
||||
#include <common/net/message/nodes/GetStatesAndBuddyGroupsRespMsg.h>
|
||||
#include <common/net/message/nodes/GetTargetMappingsRespMsg.h>
|
||||
#include <common/net/message/nodes/HeartbeatRequestMsgEx.h>
|
||||
#include <common/net/message/nodes/HeartbeatMsgEx.h>
|
||||
#include <common/net/message/nodes/MapTargetsMsgEx.h>
|
||||
#include <common/net/message/nodes/RefreshTargetStatesMsgEx.h>
|
||||
#include <common/net/message/nodes/RegisterNodeRespMsg.h>
|
||||
#include <common/net/message/nodes/RemoveNodeMsgEx.h>
|
||||
#include <common/net/message/nodes/RemoveNodeRespMsg.h>
|
||||
#include <common/net/message/nodes/SetMirrorBuddyGroupMsgEx.h>
|
||||
// storage messages
|
||||
#include <common/net/message/storage/creating/MkDirRespMsg.h>
|
||||
#include <common/net/message/storage/creating/MkFileRespMsg.h>
|
||||
#include <common/net/message/storage/creating/RmDirRespMsg.h>
|
||||
#include <common/net/message/storage/creating/HardlinkRespMsg.h>
|
||||
#include <common/net/message/storage/creating/UnlinkFileRespMsg.h>
|
||||
#include <common/net/message/storage/listing/ListDirFromOffsetRespMsg.h>
|
||||
#include <common/net/message/storage/attribs/ListXAttrRespMsg.h>
|
||||
#include <common/net/message/storage/attribs/GetXAttrRespMsg.h>
|
||||
#include <common/net/message/storage/attribs/RemoveXAttrRespMsg.h>
|
||||
#include <common/net/message/storage/attribs/SetXAttrRespMsg.h>
|
||||
#include <common/net/message/storage/attribs/RefreshEntryInfoRespMsg.h>
|
||||
#include <common/net/message/storage/moving/RenameRespMsg.h>
|
||||
#include <common/net/message/storage/lookup/LookupIntentRespMsg.h>
|
||||
#include <common/net/message/storage/attribs/SetAttrRespMsg.h>
|
||||
#include <common/net/message/storage/attribs/StatRespMsg.h>
|
||||
#include <common/net/message/storage/StatStoragePathRespMsg.h>
|
||||
#include <common/net/message/storage/TruncFileRespMsg.h>
|
||||
// session messages
|
||||
#include <common/net/message/session/opening/OpenFileRespMsg.h>
|
||||
#include <common/net/message/session/opening/CloseFileRespMsg.h>
|
||||
#include <common/net/message/session/rw/WriteLocalFileRespMsg.h>
|
||||
#ifdef BEEGFS_NVFS
|
||||
#include <common/net/message/session/rw/WriteLocalFileRDMARespMsg.h>
|
||||
#endif
|
||||
#include <common/net/message/session/BumpFileVersionResp.h>
|
||||
#include <common/net/message/session/FSyncLocalFileRespMsg.h>
|
||||
#include <common/net/message/session/GetFileVersionRespMsg.h>
|
||||
#include <common/net/message/session/locking/FLockAppendRespMsg.h>
|
||||
#include <common/net/message/session/locking/FLockEntryRespMsg.h>
|
||||
#include <common/net/message/session/locking/FLockRangeRespMsg.h>
|
||||
#include <common/net/message/session/locking/LockGrantedMsgEx.h>
|
||||
|
||||
#include <common/net/message/SimpleMsg.h>
|
||||
#include "NetMessageFactory.h"
|
||||
|
||||
|
||||
static bool __NetMessageFactory_deserializeRaw(App* app, DeserializeCtx* ctx,
|
||||
NetMessageHeader* header, NetMessage* outMsg)
|
||||
{
|
||||
bool checkCompatRes;
|
||||
bool deserPayloadRes;
|
||||
|
||||
outMsg->msgHeader = *header;
|
||||
|
||||
checkCompatRes = NetMessage_checkHeaderFeatureFlagsCompat(outMsg);
|
||||
if(unlikely(!checkCompatRes) )
|
||||
{ // incompatible feature flag was set => log error with msg type
|
||||
printk_fhgfs(KERN_NOTICE,
|
||||
"Received a message with incompatible feature flags. Message type: %hu; Flags (hex): %X",
|
||||
header->msgType, NetMessage_getMsgHeaderFeatureFlags(outMsg) );
|
||||
|
||||
_NetMessage_setMsgType(outMsg, NETMSGTYPE_Invalid);
|
||||
return false;
|
||||
}
|
||||
|
||||
// deserialize message payload
|
||||
|
||||
deserPayloadRes = outMsg->ops->deserializePayload(outMsg, ctx);
|
||||
if(unlikely(!deserPayloadRes) )
|
||||
{
|
||||
printk_fhgfs_debug(KERN_NOTICE, "Failed to decode message. Message type: %hu",
|
||||
header->msgType);
|
||||
|
||||
_NetMessage_setMsgType(outMsg, NETMSGTYPE_Invalid);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard way to create message objects from serialized message buffers.
|
||||
*
|
||||
* @return NetMessage which must be deleted by the caller
|
||||
* (msg->msgType is NETMSGTYPE_Invalid on error)
|
||||
*/
|
||||
NetMessage* NetMessageFactory_createFromBuf(App* app, char* recvBuf, size_t bufLen)
|
||||
{
|
||||
NetMessageHeader header;
|
||||
NetMessage* msg;
|
||||
DeserializeCtx ctx = {
|
||||
.data = recvBuf,
|
||||
.length = bufLen,
|
||||
};
|
||||
|
||||
// decode the message header
|
||||
__NetMessage_deserializeHeader(&ctx, &header);
|
||||
|
||||
// create the message object for the given message type
|
||||
msg = NetMessageFactory_createFromMsgType(header.msgType);
|
||||
|
||||
if(unlikely(NetMessage_getMsgType(msg) == NETMSGTYPE_Invalid) )
|
||||
{
|
||||
printk_fhgfs_debug(KERN_NOTICE,
|
||||
"Received an invalid or unhandled message. "
|
||||
"Message type (from raw header): %hu", header.msgType);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
__NetMessageFactory_deserializeRaw(app, &ctx, &header, msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special deserializer for pre-alloc'ed message objects.
|
||||
*
|
||||
* @param outMsg prealloc'ed msg of the expected type; must be initialized with the corresponding
|
||||
* deserialization-initializer; must later be uninited/destructed by the caller, no matter whether
|
||||
* this succeeds or not
|
||||
* @param expectedMsgType the type of the pre-alloc'ed message object
|
||||
* @return false on error (e.g. if real msgType does not match expectedMsgType)
|
||||
*/
|
||||
bool NetMessageFactory_deserializeFromBuf(App* app, char* recvBuf, size_t bufLen,
|
||||
NetMessage* outMsg, unsigned short expectedMsgType)
|
||||
{
|
||||
NetMessageHeader header;
|
||||
DeserializeCtx ctx = {
|
||||
.data = recvBuf,
|
||||
.length = bufLen,
|
||||
};
|
||||
|
||||
// decode the message header
|
||||
__NetMessage_deserializeHeader(&ctx, &header);
|
||||
|
||||
// verify expected message type
|
||||
if(unlikely(header.msgType != expectedMsgType) )
|
||||
return false;
|
||||
|
||||
return __NetMessageFactory_deserializeRaw(app, &ctx, &header, outMsg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return NetMessage that must be deleted by the caller
|
||||
* (msg->msgType is NETMSGTYPE_Invalid on error)
|
||||
*/
|
||||
NetMessage* NetMessageFactory_createFromMsgType(unsigned short msgType)
|
||||
{
|
||||
#define HANDLE(ID, TYPE) case NETMSGTYPE_##ID: return NETMESSAGE_CONSTRUCT(TYPE)
|
||||
|
||||
switch(msgType)
|
||||
{
|
||||
// control messages
|
||||
HANDLE(Ack, AckMsgEx);
|
||||
HANDLE(GenericResponse, GenericResponseMsg);
|
||||
// nodes messages
|
||||
HANDLE(GetNodesResp, GetNodesRespMsg);
|
||||
HANDLE(GetStatesAndBuddyGroupsResp, GetStatesAndBuddyGroupsRespMsg);
|
||||
HANDLE(GetTargetMappingsResp, GetTargetMappingsRespMsg);
|
||||
HANDLE(HeartbeatRequest, HeartbeatRequestMsgEx);
|
||||
HANDLE(Heartbeat, HeartbeatMsgEx);
|
||||
HANDLE(MapTargets, MapTargetsMsgEx);
|
||||
HANDLE(RefreshTargetStates, RefreshTargetStatesMsgEx);
|
||||
HANDLE(RegisterNodeResp, RegisterNodeRespMsg);
|
||||
HANDLE(RemoveNode, RemoveNodeMsgEx);
|
||||
HANDLE(RemoveNodeResp, RemoveNodeRespMsg);
|
||||
HANDLE(SetMirrorBuddyGroup, SetMirrorBuddyGroupMsgEx);
|
||||
// storage messages
|
||||
HANDLE(LookupIntentResp, LookupIntentRespMsg);
|
||||
HANDLE(MkDirResp, MkDirRespMsg);
|
||||
HANDLE(RmDirResp, RmDirRespMsg);
|
||||
HANDLE(MkFileResp, MkFileRespMsg);
|
||||
HANDLE(RefreshEntryInfoResp, RefreshEntryInfoRespMsg);
|
||||
HANDLE(RenameResp, RenameRespMsg);
|
||||
HANDLE(HardlinkResp, HardlinkRespMsg);;
|
||||
HANDLE(UnlinkFileResp, UnlinkFileRespMsg);
|
||||
HANDLE(ListDirFromOffsetResp, ListDirFromOffsetRespMsg);
|
||||
HANDLE(SetAttrResp, SetAttrRespMsg);
|
||||
HANDLE(StatResp, StatRespMsg);
|
||||
HANDLE(StatStoragePathResp, StatStoragePathRespMsg);
|
||||
HANDLE(TruncFileResp, TruncFileRespMsg);
|
||||
HANDLE(ListXAttrResp, ListXAttrRespMsg);
|
||||
HANDLE(GetXAttrResp, GetXAttrRespMsg);
|
||||
HANDLE(RemoveXAttrResp, RemoveXAttrRespMsg);
|
||||
HANDLE(SetXAttrResp, SetXAttrRespMsg);
|
||||
// session messages
|
||||
HANDLE(OpenFileResp, OpenFileRespMsg);
|
||||
HANDLE(CloseFileResp, CloseFileRespMsg);
|
||||
HANDLE(WriteLocalFileResp, WriteLocalFileRespMsg);
|
||||
#ifdef BEEGFS_NVFS
|
||||
HANDLE(WriteLocalFileRDMAResp, WriteLocalFileRDMARespMsg);
|
||||
#endif
|
||||
HANDLE(FSyncLocalFileResp, FSyncLocalFileRespMsg);
|
||||
HANDLE(FLockAppendResp, FLockAppendRespMsg);
|
||||
HANDLE(FLockEntryResp, FLockEntryRespMsg);
|
||||
HANDLE(FLockRangeResp, FLockRangeRespMsg);
|
||||
HANDLE(LockGranted, LockGrantedMsgEx);
|
||||
HANDLE(BumpFileVersionResp, BumpFileVersionRespMsg);
|
||||
HANDLE(GetFileVersionResp, GetFileVersionRespMsg);
|
||||
|
||||
case NETMSGTYPE_AckNotifyResp: {
|
||||
SimpleMsg* msg = os_kmalloc(sizeof(*msg));
|
||||
SimpleMsg_init(msg, msgType);
|
||||
return &msg->netMessage;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
SimpleMsg* msg = os_kmalloc(sizeof(*msg));
|
||||
SimpleMsg_init(msg, NETMSGTYPE_Invalid);
|
||||
return (NetMessage*)msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
12
client_module/source/net/message/NetMessageFactory.h
Normal file
12
client_module/source/net/message/NetMessageFactory.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef NETMESSAGEFACTORY_H_
|
||||
#define NETMESSAGEFACTORY_H_
|
||||
|
||||
#include <common/Common.h>
|
||||
#include <common/net/message/NetMessage.h>
|
||||
|
||||
extern NetMessage* NetMessageFactory_createFromBuf(App* app, char* recvBuf, size_t bufLen);
|
||||
extern bool NetMessageFactory_deserializeFromBuf(App* app, char* recvBuf, size_t bufLen,
|
||||
NetMessage* outMsg, unsigned short expectedMsgType);
|
||||
extern NetMessage* NetMessageFactory_createFromMsgType(unsigned short msgType);
|
||||
|
||||
#endif /*NETMESSAGEFACTORY_H_*/
|
||||
Reference in New Issue
Block a user