beegfs/meta/source/net/message/fsck/LinkToLostAndFoundMsgEx.cpp
2025-08-10 01:34:16 +02:00

109 lines
3.6 KiB
C++

#include "LinkToLostAndFoundMsgEx.h"
#include <common/net/message/fsck/RemoveInodesMsg.h>
#include <common/net/message/fsck/RemoveInodesRespMsg.h>
#include <program/Program.h>
#include <toolkit/BuddyCommTk.h>
bool LinkToLostAndFoundMsgEx::processIncoming(ResponseContext& ctx)
{
if (FsckDirEntryType_ISDIR(this->getEntryType()))
{
FsckDirEntryList createdDirEntries;
FsckDirInodeList failedInodes;
linkDirInodes(&failedInodes, &createdDirEntries);
ctx.sendResponse(LinkToLostAndFoundRespMsg(&failedInodes, &createdDirEntries) );
}
else
{
LOG(COMMUNICATION, ERR, "LinkToLostAndFoundMsg received for non-inlined file inode.",
("from", ctx.peerName()));
return false;
}
return true;
}
void LinkToLostAndFoundMsgEx::linkDirInodes(FsckDirInodeList* outFailedInodes,
FsckDirEntryList* outCreatedDirEntries)
{
const char* logContext = "LinkToLostAndFoundMsgEx (linkDirInodes)";
NumNodeID localNodeNumID = Program::getApp()->getLocalNode().getNumID();
FsckDirInodeList& dirInodes = getDirInodes();
MetaStore* metaStore = Program::getApp()->getMetaStore();
EntryLockStore* entryLockStore = Program::getApp()->getMirroredSessions()->getEntryLockStore();
EntryInfo* lostAndFoundInfo = this->getLostAndFoundInfo();
DirInode* lostAndFoundDir = metaStore->referenceDir(lostAndFoundInfo->getEntryID(),
lostAndFoundInfo->getIsBuddyMirrored(), true);
if ( !lostAndFoundDir )
{
*outFailedInodes = dirInodes;
return;
}
else
{
for ( FsckDirInodeListIter iter = dirInodes.begin(); iter != dirInodes.end(); iter++ )
{
const std::string& entryID = iter->getID();
NumNodeID ownerNodeID = iter->getOwnerNodeID();
DirEntryType entryType = DirEntryType_DIRECTORY;
DirEntry newDirEntry(entryType, entryID, entryID, ownerNodeID);
FileIDLock lock;
if (iter->getIsBuddyMirrored())
{
lock = {entryLockStore, entryID, true};
newDirEntry.setBuddyMirrorFeatureFlag();
}
bool makeRes = lostAndFoundDir->makeDirEntry(newDirEntry);
// stat the new file to get device and inode information
std::string filename = MetaStorageTk::getMetaDirEntryPath(
lostAndFoundInfo->getIsBuddyMirrored()
? Program::getApp()->getBuddyMirrorDentriesPath()->str()
: Program::getApp()->getDentriesPath()->str(),
lostAndFoundInfo->getEntryID()) + "/" + entryID;
struct stat statBuf;
int statRes = stat(filename.c_str(), &statBuf);
int saveDevice;
uint64_t saveInode;
if ( likely(!statRes) )
{
saveDevice = statBuf.st_dev;
saveInode = statBuf.st_ino;
}
else
{
saveDevice = 0;
saveInode = 0;
LogContext(logContext).log(Log_CRITICAL,
"Could not stat dir entry file; entryID: " + entryID + ";filename: " + filename);
}
if ( makeRes != FhgfsOpsErr_SUCCESS )
outFailedInodes->push_back(*iter);
else
{
std::string parentID = lostAndFoundInfo->getEntryID();
FsckDirEntry newFsckDirEntry(entryID, entryID, parentID, localNodeNumID,
ownerNodeID, FsckDirEntryType_DIRECTORY, false, localNodeNumID,
saveDevice, saveInode, lostAndFoundInfo->getIsBuddyMirrored());
outCreatedDirEntries->push_back(newFsckDirEntry);
}
}
lostAndFoundDir->refreshMetaInfo();
metaStore->releaseDir(lostAndFoundInfo->getEntryID() );
}
}