2025-08-10 01:34:16 +02:00

137 lines
4.8 KiB
C++

#include <common/net/message/storage/creating/MkFileRespMsg.h>
#include <common/net/message/control/GenericResponseMsg.h>
#include <common/toolkit/MessagingTk.h>
#include <common/storage/StatData.h>
#include <components/FileEventLogger.h>
#include <net/msghelpers/MsgHelperMkFile.h>
#include <program/Program.h>
#include "MkFileMsgEx.h"
std::tuple<FileIDLock, ParentNameLock, FileIDLock> MkFileMsgEx::lock(EntryLockStore& store)
{
FileIDLock dirLock(&store, getParentInfo()->getEntryID(), true);
ParentNameLock dentryLock(&store, getParentInfo()->getEntryID(), getNewName());
FileIDLock fileLock(&store, newEntryID, true);
return std::make_tuple(
std::move(dirLock),
std::move(dentryLock),
std::move(fileLock));
}
bool MkFileMsgEx::processIncoming(ResponseContext& ctx)
{
#ifdef BEEGFS_DEBUG
const char* logContext = "MkFileMsg incoming";
#endif // BEEGFS_DEBUG
LOG_DEBUG(logContext, Log_DEBUG, "parentEntryID: " +
getParentInfo()->getEntryID() + " newFileName: " + getNewName() );
LOG_DEBUG(logContext, Log_DEBUG,
"BuddyMirrored: " + std::string(getParentInfo()->getIsBuddyMirrored() ? "'Yes'" : "'No'") +
" Secondary: " + std::string(hasFlag(NetMessageHeader::Flag_BuddyMirrorSecond) ?
"Yes" : "No") );
if (!hasFlag(NetMessageHeader::Flag_BuddyMirrorSecond))
createTime = TimeAbs().getTimeval()->tv_sec;
mkDetails = {getNewName(), getUserID(), getGroupID(), getMode(), getUmask(), createTime};
if (getParentInfo()->getIsBuddyMirrored())
{
if (!hasFlag(NetMessageHeader::Flag_BuddyMirrorSecond))
newEntryID = StorageTk::generateFileID(Program::getApp()->getLocalNode().getNumID());
else
newEntryID = getNewEntryID();
mkDetails.setNewEntryID(newEntryID.c_str());
}
BaseType::processIncoming(ctx);
updateNodeOp(ctx, MetaOpCounter_MKFILE);
return true;
}
std::unique_ptr<MirroredMessageResponseState> MkFileMsgEx::executeLocally(ResponseContext& ctx,
bool isSecondary)
{
if (isSecondary)
return executeSecondary();
else
return executePrimary();
}
std::unique_ptr<MkFileMsgEx::ResponseState> MkFileMsgEx::executePrimary()
{
DirInode* dir = Program::getApp()->getMetaStore()->referenceDir(
getParentInfo()->getEntryID(), getParentInfo()->getIsBuddyMirrored(), true);
if (!dir)
return boost::make_unique<ResponseState>(FhgfsOpsErr_PATHNOTEXISTS, entryInfo);
FhgfsOpsErr mkRes;
if (isMsgHeaderFeatureFlagSet(MKFILEMSG_FLAG_STORAGEPOOLID))
{
mkRes = MsgHelperMkFile::mkFile(*dir, &mkDetails, &getPreferredNodes(),
getNumTargets(), getChunkSize(), NULL, getRemoteStorageTarget(),
&entryInfo, &inodeData, storagePoolId);
}
else
{
mkRes = MsgHelperMkFile::mkFile(*dir, &mkDetails, &getPreferredNodes(),
getNumTargets(), getChunkSize(), NULL, getRemoteStorageTarget(), &entryInfo, &inodeData);
}
if (mkRes == FhgfsOpsErr_SUCCESS && shouldFixTimestamps())
fixInodeTimestamp(*dir, dirTimestamps);
Program::getApp()->getMetaStore()->releaseDir(dir->getID());
if (mkRes == FhgfsOpsErr_SUCCESS && Program::getApp()->getFileEventLogger() && getFileEvent())
{
EventContext eventCtx = makeEventContext(&entryInfo, entryInfo.getParentEntryID(),
// This is not the secondary node if executePrimary() was called.
getMsgHeaderUserID(), "", this->inodeData.getInodeStatData()->getNumHardlinks(), false);
logEvent(Program::getApp()->getFileEventLogger(), *getFileEvent(), eventCtx);
}
return boost::make_unique<ResponseState>(mkRes, entryInfo);
}
std::unique_ptr<MkFileMsgEx::ResponseState> MkFileMsgEx::executeSecondary()
{
StripePattern* stripePattern = getPattern().clone();
FileInodeStoreData inodeData;
DirInode* dir = Program::getApp()->getMetaStore()->referenceDir(
getParentInfo()->getEntryID(), getParentInfo()->getIsBuddyMirrored(), true);
if (!dir)
return boost::make_unique<ResponseState>(FhgfsOpsErr_PATHNOTEXISTS, entryInfo);
FhgfsOpsErr mkRes = MsgHelperMkFile::mkFile(*dir, &mkDetails, &getPreferredNodes(),
getNumTargets(), getChunkSize(), stripePattern, getRemoteStorageTarget(), &entryInfo, &inodeData);
if (mkRes == FhgfsOpsErr_SUCCESS && shouldFixTimestamps())
fixInodeTimestamp(*dir, dirTimestamps);
Program::getApp()->getMetaStore()->releaseDir(dir->getID());
return boost::make_unique<ResponseState>(mkRes, entryInfo);
}
void MkFileMsgEx::forwardToSecondary(ResponseContext& ctx)
{
// secondary needs to know the created entryID and stripe pattern, because it needs to use the
// same information
setNewEntryID(newEntryID.c_str());
setPattern(inodeData.getStripePattern());
setRemoteStorageTarget(getRemoteStorageTarget());
sendToSecondary(ctx, *this, NETMSGTYPE_MkFileResp);
}