New upstream version 8.1.0
This commit is contained in:
229
meta/source/net/message/storage/creating/RmDirMsgEx.cpp
Normal file
229
meta/source/net/message/storage/creating/RmDirMsgEx.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
#include <common/components/streamlistenerv2/IncomingPreprocessedMsgWork.h>
|
||||
#include <common/net/message/control/GenericResponseMsg.h>
|
||||
#include <common/net/message/storage/creating/RmDirRespMsg.h>
|
||||
#include <common/net/message/storage/creating/RmLocalDirMsg.h>
|
||||
#include <common/net/message/storage/creating/RmLocalDirRespMsg.h>
|
||||
#include <common/toolkit/MessagingTk.h>
|
||||
#include <components/FileEventLogger.h>
|
||||
#include <components/ModificationEventFlusher.h>
|
||||
#include <program/Program.h>
|
||||
#include <session/EntryLock.h>
|
||||
#include "RmDirMsgEx.h"
|
||||
|
||||
|
||||
bool RmDirMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
BaseType::processIncoming(ctx);
|
||||
|
||||
// update operation counters
|
||||
updateNodeOp(ctx, MetaOpCounter_RMDIR);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::tuple<HashDirLock, FileIDLock, FileIDLock, ParentNameLock> RmDirMsgEx::lock(EntryLockStore& store)
|
||||
{
|
||||
MetaStore* metaStore = Program::getApp()->getMetaStore();
|
||||
EntryInfo delEntryInfo;
|
||||
|
||||
DirInode* parentDir = metaStore->referenceDir(
|
||||
getParentInfo()->getEntryID(), getParentInfo()->getIsBuddyMirrored(), true);
|
||||
if (!parentDir)
|
||||
return {};
|
||||
else
|
||||
{
|
||||
parentDir->getDirEntryInfo(getDelDirName(), delEntryInfo);
|
||||
metaStore->releaseDir(getParentInfo()->getEntryID());
|
||||
}
|
||||
|
||||
FileIDLock parentDirLock;
|
||||
FileIDLock delDirLock;
|
||||
HashDirLock hashLock;
|
||||
|
||||
if (resyncJob && resyncJob->isRunning())
|
||||
hashLock = {&store, MetaStorageTk::getMetaInodeHash(delEntryInfo.getEntryID())};
|
||||
|
||||
// lock directories in deadlock-avoidance order, see MirroredMessage::lock()
|
||||
if (delEntryInfo.getEntryID().empty())
|
||||
{
|
||||
parentDirLock = {&store, getParentInfo()->getEntryID(), true};
|
||||
}
|
||||
else if (delEntryInfo.getEntryID() < getParentInfo()->getEntryID())
|
||||
{
|
||||
delDirLock = {&store, delEntryInfo.getEntryID(), true};
|
||||
parentDirLock = {&store, getParentInfo()->getEntryID(), true};
|
||||
}
|
||||
else if (delEntryInfo.getEntryID() == getParentInfo()->getEntryID())
|
||||
{
|
||||
delDirLock = {&store, delEntryInfo.getEntryID(), true};
|
||||
}
|
||||
else
|
||||
{
|
||||
parentDirLock = {&store, getParentInfo()->getEntryID(), true};
|
||||
delDirLock = {&store, delEntryInfo.getEntryID(), true};
|
||||
}
|
||||
|
||||
ParentNameLock parentNameLock(&store, getParentInfo()->getEntryID(), getDelDirName());
|
||||
|
||||
return std::make_tuple(
|
||||
std::move(hashLock),
|
||||
std::move(parentDirLock),
|
||||
std::move(delDirLock),
|
||||
std::move(parentNameLock));
|
||||
}
|
||||
|
||||
std::unique_ptr<RmDirMsgEx::ResponseState> RmDirMsgEx::rmDir(ResponseContext& ctx,
|
||||
const bool isSecondary)
|
||||
{
|
||||
App* app = Program::getApp();
|
||||
MetaStore* metaStore = Program::getApp()->getMetaStore();
|
||||
ModificationEventFlusher* modEventFlusher = Program::getApp()->getModificationEventFlusher();
|
||||
bool modEventLoggingEnabled = modEventFlusher->isLoggingEnabled();
|
||||
|
||||
FhgfsOpsErr retVal;
|
||||
|
||||
EntryInfo* parentInfo = this->getParentInfo();
|
||||
const std::string& delDirName = this->getDelDirName();
|
||||
|
||||
EntryInfo outDelEntryInfo;
|
||||
|
||||
// reference parent
|
||||
DirInode* parentDir = metaStore->referenceDir(parentInfo->getEntryID(),
|
||||
parentInfo->getIsBuddyMirrored(), true);
|
||||
if(!parentDir)
|
||||
return boost::make_unique<ResponseState>(FhgfsOpsErr_PATHNOTEXISTS);
|
||||
|
||||
DirEntry removeDirEntry(delDirName);
|
||||
bool getEntryRes = parentDir->getDirDentry(delDirName, removeDirEntry);
|
||||
if(!getEntryRes)
|
||||
retVal = FhgfsOpsErr_PATHNOTEXISTS;
|
||||
else
|
||||
{
|
||||
int additionalFlags = 0;
|
||||
|
||||
const std::string& parentEntryID = parentInfo->getEntryID();
|
||||
removeDirEntry.getEntryInfo(parentEntryID, additionalFlags, &outDelEntryInfo);
|
||||
|
||||
App* app = Program::getApp();
|
||||
NumNodeID ownerNodeID = outDelEntryInfo.getOwnerNodeID();
|
||||
|
||||
// no-comms path: the dir inode is owned by us
|
||||
if ((!isMirrored() && ownerNodeID == app->getLocalNode().getNumID()) ||
|
||||
(isMirrored() &&
|
||||
ownerNodeID.val() == app->getMetaBuddyGroupMapper()->getLocalGroupID()))
|
||||
retVal = app->getMetaStore()->removeDirInode(outDelEntryInfo.getEntryID(),
|
||||
outDelEntryInfo.getIsBuddyMirrored());
|
||||
else if (!isSecondary)
|
||||
retVal = rmRemoteDirInode(&outDelEntryInfo);
|
||||
else
|
||||
retVal = FhgfsOpsErr_SUCCESS;
|
||||
|
||||
if(retVal == FhgfsOpsErr_SUCCESS)
|
||||
{ // local removal succeeded => remove meta dir
|
||||
retVal = parentDir->removeDir(delDirName, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (retVal == FhgfsOpsErr_SUCCESS && shouldFixTimestamps())
|
||||
fixInodeTimestamp(*parentDir, dirTimestamps);
|
||||
|
||||
// clean-up
|
||||
metaStore->releaseDir(parentInfo->getEntryID() );
|
||||
|
||||
if (!isSecondary && retVal == FhgfsOpsErr_SUCCESS && app->getFileEventLogger() && getFileEvent())
|
||||
{
|
||||
EventContext eventCtx = makeEventContext(&outDelEntryInfo, outDelEntryInfo.getParentEntryID(),
|
||||
getMsgHeaderUserID(), "", 0, isSecondary);
|
||||
logEvent(app->getFileEventLogger(), *getFileEvent(), eventCtx);
|
||||
}
|
||||
|
||||
if (retVal == FhgfsOpsErr_SUCCESS && modEventLoggingEnabled)
|
||||
{
|
||||
const std::string& entryID = outDelEntryInfo.getEntryID();
|
||||
modEventFlusher->add(ModificationEvent_DIRREMOVED, entryID);
|
||||
}
|
||||
|
||||
return boost::make_unique<ResponseState>(retVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inode of this directory
|
||||
*/
|
||||
FhgfsOpsErr RmDirMsgEx::rmRemoteDirInode(EntryInfo* delEntryInfo)
|
||||
{
|
||||
const char* logContext = "RmDirMsg (rm dir inode)";
|
||||
|
||||
FhgfsOpsErr retVal = FhgfsOpsErr_SUCCESS;
|
||||
|
||||
App* app = Program::getApp();
|
||||
NumNodeID ownerNodeID = delEntryInfo->getOwnerNodeID();
|
||||
|
||||
LOG_DEBUG(logContext, Log_DEBUG,
|
||||
"Removing dir inode from metadata node: " + ownerNodeID.str() + "; "
|
||||
"dirname: " + delEntryInfo->getFileName() + "; isBuddyMirrored: " +
|
||||
StringTk::intToStr(delEntryInfo->getIsBuddyMirrored()) );
|
||||
|
||||
// prepare request
|
||||
|
||||
RmLocalDirMsg rmMsg(delEntryInfo);
|
||||
|
||||
RequestResponseArgs rrArgs(NULL, &rmMsg, NETMSGTYPE_RmLocalDirResp);
|
||||
|
||||
RequestResponseNode rrNode(ownerNodeID, app->getMetaNodes() );
|
||||
rrNode.setTargetStates(app->getMetaStateStore() );
|
||||
|
||||
if (delEntryInfo->getIsBuddyMirrored())
|
||||
rrNode.setMirrorInfo(app->getMetaBuddyGroupMapper(), false);
|
||||
|
||||
do // (this loop just exists to enable the "break"-jump, so it's not really a loop)
|
||||
{
|
||||
// send request to other mds and receive response
|
||||
|
||||
FhgfsOpsErr requestRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);
|
||||
|
||||
if(requestRes != FhgfsOpsErr_SUCCESS)
|
||||
{ // communication error
|
||||
LogContext(logContext).log(Log_WARNING,
|
||||
"Communication with metadata server failed. "
|
||||
"ownerNodeID: " + ownerNodeID.str() + "; "
|
||||
"dirID: " + delEntryInfo->getEntryID() + "; " +
|
||||
"dirname: " + delEntryInfo->getFileName() );
|
||||
retVal = requestRes;
|
||||
break;
|
||||
}
|
||||
|
||||
// correct response type received
|
||||
const auto rmRespMsg = (const RmLocalDirRespMsg*)rrArgs.outRespMsg.get();
|
||||
|
||||
retVal = rmRespMsg->getResult();
|
||||
if(unlikely( (retVal != FhgfsOpsErr_SUCCESS) && (retVal != FhgfsOpsErr_NOTEMPTY) ) )
|
||||
{ // error: dir inode not removed
|
||||
std::string errString = boost::lexical_cast<std::string>(retVal);
|
||||
|
||||
LogContext(logContext).log(Log_DEBUG,
|
||||
"Metadata server was unable to remove dir inode. "
|
||||
"ownerNodeID: " + ownerNodeID.str() + "; "
|
||||
"dirID: " + delEntryInfo->getEntryID() + "; " +
|
||||
"dirname: " + delEntryInfo->getFileName() + "; " +
|
||||
"error: " + errString);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// success: dir inode removed
|
||||
LOG_DEBUG(logContext, Log_DEBUG,
|
||||
"Metadata server removed dir inode: "
|
||||
"ownerNodeID: " + ownerNodeID.str() + "; "
|
||||
"dirID: " + delEntryInfo->getEntryID() + "; " +
|
||||
"dirname: " + delEntryInfo->getFileName() );
|
||||
|
||||
} while(false);
|
||||
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void RmDirMsgEx::forwardToSecondary(ResponseContext& ctx)
|
||||
{
|
||||
sendToSecondary(ctx, *this, NETMSGTYPE_RmDirResp);
|
||||
}
|
||||
Reference in New Issue
Block a user