beegfs/meta/source/net/message/storage/lookup/LookupIntentMsgEx.h
2025-08-10 01:34:16 +02:00

223 lines
7.4 KiB
C++

#pragma once
#include <common/net/message/storage/lookup/LookupIntentMsg.h>
#include <common/net/message/storage/lookup/LookupIntentRespMsg.h>
#include <common/nodes/OpCounterTypes.h>
#include <common/storage/StorageDefinitions.h>
#include <common/storage/StorageErrors.h>
#include <common/toolkit/MetadataTk.h>
#include <common/Common.h>
#include <storage/MetaStore.h>
#include <net/message/MirroredMessage.h>
class LookupIntentResponseState : public MirroredMessageResponseState
{
public:
LookupIntentResponseState() :
responseFlags(0), lookupResult(FhgfsOpsErr_INTERNAL), statResult(FhgfsOpsErr_INTERNAL),
revalidateResult(FhgfsOpsErr_INTERNAL), createResult(FhgfsOpsErr_INTERNAL),
openResult(FhgfsOpsErr_INTERNAL)
{}
explicit LookupIntentResponseState(Deserializer& des)
{
serialize(this, des);
}
LookupIntentResponseState(LookupIntentResponseState&& other) :
responseFlags(other.responseFlags),
lookupResult(other.lookupResult),
statResult(other.statResult),
statData(other.statData),
revalidateResult(other.revalidateResult),
createResult(other.createResult),
openResult(other.openResult),
fileHandleID(std::move(other.fileHandleID)),
entryInfo(std::move(other.entryInfo)),
pattern(std::move(other.pattern)),
pathInfo(std::move(other.pathInfo))
{}
void sendResponse(NetMessage::ResponseContext& ctx) override
{
LookupIntentRespMsg resp(lookupResult);
if (responseFlags & LOOKUPINTENTRESPMSG_FLAG_STAT)
resp.addResponseStat(statResult, &statData);
if (responseFlags & LOOKUPINTENTRESPMSG_FLAG_REVALIDATE)
resp.addResponseRevalidate(revalidateResult);
if (responseFlags & LOOKUPINTENTRESPMSG_FLAG_CREATE)
resp.addResponseCreate(createResult);
if (responseFlags & LOOKUPINTENTRESPMSG_FLAG_OPEN)
resp.addResponseOpen(openResult, fileHandleID, pattern.get(), &pathInfo);
resp.setEntryInfo(&entryInfo);
ctx.sendResponse(resp);
}
bool changesObservableState() const override
{
if ((responseFlags & LOOKUPINTENTRESPMSG_FLAG_CREATE)
&& createResult == FhgfsOpsErr_SUCCESS)
return true;
if ((responseFlags & LOOKUPINTENTRESPMSG_FLAG_OPEN) && openResult == FhgfsOpsErr_SUCCESS)
return true;
return false;
}
protected:
uint32_t serializerTag() const override { return NETMSGTYPE_LookupIntent; }
template<typename This, typename Ctx>
static void serialize(This* obj, Ctx& ctx)
{
ctx
% obj->responseFlags
% serdes::as<int32_t>(obj->lookupResult);
if (obj->responseFlags & LOOKUPINTENTRESPMSG_FLAG_STAT)
ctx
% obj->statData.serializeAs(StatDataFormat_NET)
% serdes::as<int32_t>(obj->statResult);
ctx
% serdes::as<int32_t>(obj->revalidateResult)
% serdes::as<int32_t>(obj->createResult);
if (obj->responseFlags & LOOKUPINTENTRESPMSG_FLAG_OPEN)
ctx
% serdes::as<int32_t>(obj->openResult)
% obj->fileHandleID
% obj->entryInfo
% obj->pattern
% obj->pathInfo;
}
void serializeContents(Serializer& ser) const override
{
serialize(this, ser);
}
private:
int32_t responseFlags;
FhgfsOpsErr lookupResult;
FhgfsOpsErr statResult;
StatData statData;
FhgfsOpsErr revalidateResult;
FhgfsOpsErr createResult;
FhgfsOpsErr openResult;
std::string fileHandleID;
EntryInfo entryInfo;
std::unique_ptr<StripePattern> pattern;
PathInfo pathInfo;
public:
void setLookupResult(FhgfsOpsErr lookupRes) { lookupResult = lookupRes; }
void addResponseRevalidate(FhgfsOpsErr revalidateResult)
{
responseFlags |= LOOKUPINTENTRESPMSG_FLAG_REVALIDATE;
this->revalidateResult = revalidateResult;
}
void addResponseCreate(FhgfsOpsErr createResult)
{
responseFlags |= LOOKUPINTENTRESPMSG_FLAG_CREATE;
this->createResult = createResult;
}
void addResponseOpen(FhgfsOpsErr openResult, std::string fileHandleID,
std::unique_ptr<StripePattern> pattern, const PathInfo& pathInfo)
{
responseFlags |= LOOKUPINTENTRESPMSG_FLAG_OPEN;
this->openResult = openResult;
this->fileHandleID = std::move(fileHandleID);
this->pattern = std::move(pattern);
this->pathInfo = pathInfo;
}
void addResponseStat(FhgfsOpsErr statResult, const StatData& statData)
{
responseFlags |= LOOKUPINTENTRESPMSG_FLAG_STAT;
this->statResult = statResult;
this->statData = statData;
}
void setEntryInfo(EntryInfo value) { entryInfo = std::move(value); }
};
/**
* This combines the normal lookup of a directory entry with intents, i.e. options to create,
* open and stat the entry in a single message.
*
* Note: The intent options currently work only for files.
*/
class LookupIntentMsgEx : public MirroredMessage<LookupIntentMsg,
std::tuple<FileIDLock, ParentNameLock, FileIDLock>>
{
public:
typedef LookupIntentResponseState ResponseState;
virtual bool processIncoming(ResponseContext& ctx) override;
std::tuple<FileIDLock, ParentNameLock, FileIDLock> lock(EntryLockStore& store) override;
bool isMirrored() override { return getParentInfo()->getIsBuddyMirrored(); }
const char* mirrorLogContext() const override { return "LookupIntentMsgEx/forward"; }
std::unique_ptr<MirroredMessageResponseState> executeLocally(ResponseContext& ctx,
bool isSecondary) override;
FhgfsOpsErr processSecondaryResponse(NetMessage& resp) override
{
auto& respMsg = static_cast<LookupIntentRespMsg&>(resp);
// since we only forward for open and create, we need only check those two.
if ((respMsg.getResponseFlags() & LOOKUPINTENTRESPMSG_FLAG_CREATE)
&& respMsg.getCreateResult() != FhgfsOpsErr_SUCCESS)
return respMsg.getCreateResult();
if ((respMsg.getResponseFlags() & LOOKUPINTENTRESPMSG_FLAG_OPEN)
&& respMsg.getOpenResult() != FhgfsOpsErr_SUCCESS)
return respMsg.getOpenResult();
return FhgfsOpsErr_SUCCESS;
}
private:
FhgfsOpsErr lookup(const std::string& parentEntryID, const std::string& entryName,
bool isBuddyMirrored, EntryInfo* outEntryInfo, FileInodeStoreData* outInodeStoreData,
bool& outInodeDataOutdated);
FhgfsOpsErr revalidate(EntryInfo* diskEntryInfo, uint32_t metaVersion);
FhgfsOpsErr create(EntryInfo* parentInfo, const std::string& entryName,
EntryInfo* outEntryInfo, FileInodeStoreData* outInodeData, bool isSecondary);
FhgfsOpsErr stat(EntryInfo* entryInfo, bool loadFromDisk, StatData& outStatData);
FhgfsOpsErr open(EntryInfo* entryInfo, std::string* outFileHandleID,
StripePattern** outPattern, PathInfo* outPathInfo, bool isSecondary);
void forwardToSecondary(ResponseContext& ctx) override;
MetaOpCounterTypes getOpCounterType();
FileInodeStoreData inodeData;
std::string entryID;
FhgfsOpsErr lookupRes;
bool inodeDataOutdated;
EntryInfo diskEntryInfo;
};