New upstream version 8.1.0
This commit is contained in:
213
meta/source/net/message/fsck/AdjustChunkPermissionsMsgEx.cpp
Normal file
213
meta/source/net/message/fsck/AdjustChunkPermissionsMsgEx.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
#include "AdjustChunkPermissionsMsgEx.h"
|
||||
|
||||
#include <program/Program.h>
|
||||
#include <common/net/message/storage/attribs/SetLocalAttrMsg.h>
|
||||
#include <common/net/message/storage/attribs/SetLocalAttrRespMsg.h>
|
||||
#include <common/storage/striping/Raid0Pattern.h>
|
||||
#include <components/worker/SetChunkFileAttribsWork.h>
|
||||
|
||||
bool AdjustChunkPermissionsMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("Incoming AdjustChunkPermissionsMsg");
|
||||
|
||||
MetaStore *metaStore = Program::getApp()->getMetaStore();
|
||||
|
||||
unsigned hashDirNum = this->getHashDirNum();
|
||||
unsigned maxEntries = this->getMaxEntries();
|
||||
int64_t lastHashDirOffset = this->getLastHashDirOffset();
|
||||
int64_t lastContDirOffset = this->getLastContDirOffset();
|
||||
std::string currentContDirID = this->getCurrentContDirID();
|
||||
int64_t newHashDirOffset = 0;
|
||||
int64_t newContDirOffset = 0;
|
||||
unsigned errorCount = 0;
|
||||
|
||||
unsigned readOutEntries = 0;
|
||||
|
||||
bool hasNext;
|
||||
|
||||
if ( currentContDirID.empty() )
|
||||
{
|
||||
hasNext = StorageTkEx::getNextContDirID(hashDirNum, getIsBuddyMirrored(), lastHashDirOffset,
|
||||
¤tContDirID, &newHashDirOffset);
|
||||
if ( hasNext )
|
||||
{
|
||||
lastHashDirOffset = newHashDirOffset;
|
||||
}
|
||||
}
|
||||
else
|
||||
hasNext = true;
|
||||
|
||||
while ( hasNext )
|
||||
{
|
||||
std::string parentID = currentContDirID;
|
||||
|
||||
unsigned remainingEntries = maxEntries - readOutEntries;
|
||||
StringList entryNames;
|
||||
|
||||
bool parentDirInodeIsTemp = false;
|
||||
|
||||
FileIDLock dirLock;
|
||||
|
||||
if (getIsBuddyMirrored())
|
||||
dirLock = {Program::getApp()->getMirroredSessions()->getEntryLockStore(), parentID, false};
|
||||
|
||||
DirInode* parentDirInode = metaStore->referenceDir(parentID, getIsBuddyMirrored(), true);
|
||||
|
||||
// it could be, that parentDirInode does not exist
|
||||
// in fsck we create a temporary inode for this case
|
||||
if ( unlikely(!parentDirInode) )
|
||||
{
|
||||
log.log(
|
||||
Log_NOTICE,
|
||||
"Could not reference directory. EntryID: " + parentID
|
||||
+ " => using temporary directory inode ");
|
||||
|
||||
// create temporary inode
|
||||
int mode = S_IFDIR | S_IRWXU;
|
||||
UInt16Vector stripeTargets;
|
||||
Raid0Pattern stripePattern(0, stripeTargets, 0);
|
||||
parentDirInode = new DirInode(parentID, mode, 0, 0,
|
||||
Program::getApp()->getLocalNode().getNumID(), stripePattern, getIsBuddyMirrored());
|
||||
|
||||
parentDirInodeIsTemp = true;
|
||||
}
|
||||
|
||||
if ( parentDirInode->listIncremental(lastContDirOffset, remainingEntries, &entryNames,
|
||||
&newContDirOffset) == FhgfsOpsErr_SUCCESS )
|
||||
{
|
||||
lastContDirOffset = newContDirOffset;
|
||||
readOutEntries += entryNames.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
log.log(Log_WARNING, "Could not list contents of directory. EntryID: " + parentID);
|
||||
}
|
||||
|
||||
// actually process the entries; for the dentry part we only need to know if it is a file
|
||||
// with inlined inode data
|
||||
for ( StringListIter namesIter = entryNames.begin(); namesIter != entryNames.end();
|
||||
namesIter++ )
|
||||
{
|
||||
std::string filename = MetaStorageTk::getMetaDirEntryPath(
|
||||
getIsBuddyMirrored()
|
||||
? Program::getApp()->getBuddyMirrorDentriesPath()->str()
|
||||
: Program::getApp()->getDentriesPath()->str(), parentID) + "/" + *namesIter;
|
||||
|
||||
EntryInfo entryInfo;
|
||||
FileInodeStoreData inodeDiskData;
|
||||
|
||||
auto [getEntryRes, isFileOpen] = metaStore->getEntryData(parentDirInode, *namesIter, &entryInfo,
|
||||
&inodeDiskData);
|
||||
inodeDiskData.setDynamicOrigParentEntryID(parentID);
|
||||
|
||||
if (getEntryRes == FhgfsOpsErr_SUCCESS ||
|
||||
getEntryRes == FhgfsOpsErr_DYNAMICATTRIBSOUTDATED )
|
||||
{
|
||||
DirEntryType entryType = entryInfo.getEntryType();
|
||||
|
||||
// we only care if inode data is present
|
||||
if ( (DirEntryType_ISFILE(entryType)) && (entryInfo.getIsInlined() ) )
|
||||
{
|
||||
const std::string& inodeID = inodeDiskData.getEntryID();
|
||||
unsigned userID = inodeDiskData.getInodeStatData()->getUserID();
|
||||
unsigned groupID = inodeDiskData.getInodeStatData()->getGroupID();
|
||||
StripePattern* pattern = inodeDiskData.getStripePattern();
|
||||
|
||||
PathInfo pathInfo;
|
||||
inodeDiskData.getPathInfo(&pathInfo);
|
||||
|
||||
if ( !this->sendSetAttrMsg(inodeID, userID, groupID, &pathInfo, pattern) )
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log.log(Log_WARNING, "Unable to create dir entry from entry with name " + *namesIter
|
||||
+ " in directory with ID " + parentID);
|
||||
}
|
||||
}
|
||||
|
||||
if ( parentDirInodeIsTemp )
|
||||
SAFE_DELETE(parentDirInode);
|
||||
else
|
||||
metaStore->releaseDir(parentID);
|
||||
|
||||
if ( entryNames.size() < remainingEntries )
|
||||
{
|
||||
// directory is at the end => proceed with next
|
||||
hasNext = StorageTkEx::getNextContDirID(hashDirNum, getIsBuddyMirrored(),
|
||||
lastHashDirOffset, ¤tContDirID, &newHashDirOffset);
|
||||
|
||||
if ( hasNext )
|
||||
{
|
||||
lastHashDirOffset = newHashDirOffset;
|
||||
lastContDirOffset = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// there are more to come, but we need to exit the loop now, because maxCount is reached
|
||||
hasNext = false;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.sendResponse(
|
||||
AdjustChunkPermissionsRespMsg(readOutEntries, currentContDirID, lastHashDirOffset,
|
||||
lastContDirOffset, errorCount) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AdjustChunkPermissionsMsgEx::sendSetAttrMsg(const std::string& entryID, unsigned userID,
|
||||
unsigned groupID, PathInfo* pathInfo, StripePattern* pattern)
|
||||
{
|
||||
const char* logContext = "AdjustChunkPermissionsMsgEx::sendSetAttrMsg";
|
||||
|
||||
MultiWorkQueue* slaveQueue = Program::getApp()->getCommSlaveQueue();
|
||||
|
||||
int validAttribs = SETATTR_CHANGE_USERID | SETATTR_CHANGE_GROUPID; // only interested in these
|
||||
SettableFileAttribs attribs;
|
||||
attribs.userID = userID;
|
||||
attribs.groupID = groupID;
|
||||
|
||||
const UInt16Vector* stripeTargets = pattern->getStripeTargetIDs();
|
||||
size_t numTargetWorks = stripeTargets->size();
|
||||
|
||||
FhgfsOpsErrVec nodeResults(numTargetWorks);
|
||||
SynchronizedCounter counter;
|
||||
|
||||
// generate work for storage targets...
|
||||
|
||||
for(size_t i=0; i < numTargetWorks; i++)
|
||||
{
|
||||
SetChunkFileAttribsWork* work = new SetChunkFileAttribsWork(
|
||||
entryID, validAttribs, &attribs, false, pattern, (*stripeTargets)[i], pathInfo,
|
||||
NULL, &(nodeResults[i]), &counter);
|
||||
|
||||
work->setQuotaChown(true);
|
||||
work->setMsgUserID(getMsgHeaderUserID() );
|
||||
|
||||
slaveQueue->addDirectWork(work);
|
||||
}
|
||||
|
||||
// wait for work completion...
|
||||
|
||||
counter.waitForCount(numTargetWorks);
|
||||
|
||||
// check target results...
|
||||
|
||||
for(size_t i=0; i < numTargetWorks; i++)
|
||||
{
|
||||
if(unlikely(nodeResults[i] != FhgfsOpsErr_SUCCESS) )
|
||||
{
|
||||
LogContext(logContext).log(Log_WARNING,
|
||||
"Problems occurred during setting of chunk file attribs. "
|
||||
"fileID: " + entryID );
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
17
meta/source/net/message/fsck/AdjustChunkPermissionsMsgEx.h
Normal file
17
meta/source/net/message/fsck/AdjustChunkPermissionsMsgEx.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/fsck/AdjustChunkPermissionsMsg.h>
|
||||
#include <common/net/message/fsck/AdjustChunkPermissionsRespMsg.h>
|
||||
#include <common/storage/PathInfo.h>
|
||||
#include <common/storage/striping/StripePattern.h>
|
||||
|
||||
class AdjustChunkPermissionsMsgEx : public AdjustChunkPermissionsMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
|
||||
private:
|
||||
bool sendSetAttrMsg(const std::string& entryID, unsigned userID, unsigned groupID,
|
||||
PathInfo* pathInfo, StripePattern* pattern);
|
||||
};
|
||||
|
||||
38
meta/source/net/message/fsck/CheckAndRepairDupInodeMsgEx.cpp
Normal file
38
meta/source/net/message/fsck/CheckAndRepairDupInodeMsgEx.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <program/Program.h>
|
||||
#include <common/net/message/fsck/CheckAndRepairDupInodeRespMsg.h>
|
||||
|
||||
#include "CheckAndRepairDupInodeMsgEx.h"
|
||||
|
||||
bool CheckAndRepairDupInodeMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
MetaStore* metaStore = Program::getApp()->getMetaStore();
|
||||
EntryLockStore* entryLockStore = Program::getApp()->getMirroredSessions()->getEntryLockStore();
|
||||
|
||||
StringList failedIDList;
|
||||
|
||||
for (const auto& inode : getDuplicateInodes())
|
||||
{
|
||||
const std::string& entryID = inode.getID();
|
||||
const std::string& parentEntryID = inode.getParentDirID();
|
||||
const bool isBuddyMirrored = inode.getIsBuddyMirrored();
|
||||
|
||||
FileIDLock dirLock = {entryLockStore, parentEntryID, true};
|
||||
FileIDLock fileLock = {entryLockStore, entryID, true};
|
||||
|
||||
EntryInfo fileInfo(NumNodeID(0), parentEntryID, entryID, std::string(""), DirEntryType_REGULARFILE, 0);
|
||||
fileInfo.setBuddyMirroredFlag(isBuddyMirrored);
|
||||
|
||||
DirInode* parentDir = metaStore->referenceDir(parentEntryID, isBuddyMirrored, true);
|
||||
FhgfsOpsErr repairRes = metaStore->checkAndRepairDupFileInode(*parentDir, &fileInfo);
|
||||
|
||||
if (repairRes != FhgfsOpsErr_SUCCESS)
|
||||
{
|
||||
failedIDList.push_back(entryID);
|
||||
}
|
||||
|
||||
metaStore->releaseDir(parentDir->getID());
|
||||
}
|
||||
|
||||
ctx.sendResponse(CheckAndRepairDupInodeRespMsg(std::move(failedIDList)));
|
||||
return true;
|
||||
}
|
||||
10
meta/source/net/message/fsck/CheckAndRepairDupInodeMsgEx.h
Normal file
10
meta/source/net/message/fsck/CheckAndRepairDupInodeMsgEx.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/fsck/CheckAndRepairDupInodeMsg.h>
|
||||
|
||||
class CheckAndRepairDupInodeMsgEx : public CheckAndRepairDupInodeMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
60
meta/source/net/message/fsck/CreateDefDirInodesMsgEx.cpp
Normal file
60
meta/source/net/message/fsck/CreateDefDirInodesMsgEx.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "CreateDefDirInodesMsgEx.h"
|
||||
#include <program/Program.h>
|
||||
#include <toolkit/BuddyCommTk.h>
|
||||
|
||||
bool CreateDefDirInodesMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("CreateDefDirInodesMsg incoming");
|
||||
|
||||
App* app = Program::getApp();
|
||||
Config* cfg = app->getConfig();
|
||||
|
||||
StringList failedInodeIDs;
|
||||
FsckDirInodeList createdInodes;
|
||||
|
||||
for (auto it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
const std::string& inodeID = std::get<0>(*it);
|
||||
const bool isBuddyMirrored = std::get<1>(*it);
|
||||
int mode = S_IFDIR | S_IRWXU;
|
||||
unsigned userID = 0; // root
|
||||
unsigned groupID = 0; // root
|
||||
const NumNodeID ownerNodeID = isBuddyMirrored
|
||||
? NumNodeID(app->getMetaBuddyGroupMapper()->getLocalGroupID())
|
||||
: app->getLocalNode().getNumID();
|
||||
|
||||
UInt16Vector stripeTargets;
|
||||
unsigned defaultChunkSize = cfg->getTuneDefaultChunkSize();
|
||||
unsigned defaultNumStripeTargets = cfg->getTuneDefaultNumStripeTargets();
|
||||
Raid0Pattern stripePattern(defaultChunkSize, stripeTargets, defaultNumStripeTargets);
|
||||
|
||||
// we try to create a new directory inode, with default values
|
||||
|
||||
FileIDLock dirLock;
|
||||
|
||||
if (isBuddyMirrored)
|
||||
dirLock = {Program::getApp()->getMirroredSessions()->getEntryLockStore(), inodeID, true};
|
||||
|
||||
DirInode dirInode(inodeID, mode, userID, groupID, ownerNodeID, stripePattern,
|
||||
isBuddyMirrored);
|
||||
if ( dirInode.storeAsReplacementFile(inodeID) == FhgfsOpsErr_SUCCESS )
|
||||
{
|
||||
// try to refresh the metainfo (maybe a .cont directory was already present)
|
||||
dirInode.refreshMetaInfo();
|
||||
|
||||
StatData statData;
|
||||
dirInode.getStatData(statData);
|
||||
|
||||
FsckDirInode fsckDirInode(inodeID, "", NumNodeID(), ownerNodeID, statData.getFileSize(),
|
||||
statData.getNumHardlinks(), stripeTargets, FsckStripePatternType_RAID0,
|
||||
ownerNodeID, isBuddyMirrored, true, false);
|
||||
createdInodes.push_back(fsckDirInode);
|
||||
}
|
||||
else
|
||||
failedInodeIDs.push_back(inodeID);
|
||||
}
|
||||
|
||||
ctx.sendResponse(CreateDefDirInodesRespMsg(&failedInodeIDs, &createdInodes) );
|
||||
|
||||
return true;
|
||||
}
|
||||
12
meta/source/net/message/fsck/CreateDefDirInodesMsgEx.h
Normal file
12
meta/source/net/message/fsck/CreateDefDirInodesMsgEx.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/storage/striping/Raid0Pattern.h>
|
||||
#include <common/net/message/fsck/CreateDefDirInodesMsg.h>
|
||||
#include <common/net/message/fsck/CreateDefDirInodesRespMsg.h>
|
||||
|
||||
class CreateDefDirInodesMsgEx : public CreateDefDirInodesMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
77
meta/source/net/message/fsck/CreateEmptyContDirsMsgEx.cpp
Normal file
77
meta/source/net/message/fsck/CreateEmptyContDirsMsgEx.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "CreateEmptyContDirsMsgEx.h"
|
||||
#include <program/Program.h>
|
||||
#include <toolkit/BuddyCommTk.h>
|
||||
|
||||
bool CreateEmptyContDirsMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
const char* logContext = "CreateEmptyContDirsMsg incoming";
|
||||
|
||||
App* app = Program::getApp();
|
||||
MetaStore* metaStore = app->getMetaStore();
|
||||
|
||||
StringList failedIDs;
|
||||
|
||||
for (auto iter = items.begin(); iter != items.end(); iter++)
|
||||
{
|
||||
const std::string& dirID = std::get<0>(*iter);
|
||||
const bool isBuddyMirrored = std::get<1>(*iter);
|
||||
|
||||
std::string contentsDirStr = MetaStorageTk::getMetaDirEntryPath(
|
||||
isBuddyMirrored
|
||||
? app->getBuddyMirrorDentriesPath()->str()
|
||||
: app->getDentriesPath()->str(), dirID);
|
||||
|
||||
// create contents directory
|
||||
int mkRes = mkdir(contentsDirStr.c_str(), 0755);
|
||||
|
||||
if ( mkRes != 0 )
|
||||
{ // error
|
||||
LOG(GENERAL, ERR, "Unable to create contents directory.", contentsDirStr, sysErr);
|
||||
failedIDs.push_back(dirID);
|
||||
continue;
|
||||
}
|
||||
|
||||
// create the dirEntryID directory, which allows access to inlined inodes via dirID access
|
||||
std::string contentsDirIDStr = MetaStorageTk::getMetaDirEntryIDPath(contentsDirStr);
|
||||
|
||||
int mkDirIDRes = mkdir(contentsDirIDStr.c_str(), 0755);
|
||||
|
||||
if ( mkDirIDRes != 0 )
|
||||
{ // error
|
||||
LOG(GENERAL, ERR, "Unable to create dirEntryID directory.", contentsDirIDStr, sysErr);
|
||||
failedIDs.push_back(dirID);
|
||||
continue;
|
||||
}
|
||||
|
||||
FileIDLock lock;
|
||||
|
||||
if (isBuddyMirrored)
|
||||
lock = {Program::getApp()->getMirroredSessions()->getEntryLockStore(), dirID, true};
|
||||
|
||||
// update the dir attribs
|
||||
|
||||
DirInode* dirInode = metaStore->referenceDir(dirID, isBuddyMirrored, true);
|
||||
|
||||
if (!dirInode)
|
||||
{
|
||||
LOG(GENERAL, ERR, "Unable to reference directory.", dirID);
|
||||
failedIDs.push_back(dirID);
|
||||
continue;
|
||||
}
|
||||
|
||||
FhgfsOpsErr refreshRes = dirInode->refreshMetaInfo();
|
||||
|
||||
if (refreshRes != FhgfsOpsErr_SUCCESS)
|
||||
{
|
||||
LogContext(logContext).log(Log_NOTICE, "Unable to refresh contents directory metadata: "
|
||||
+ contentsDirStr + ". " + "SysErr: " + System::getErrString());
|
||||
}
|
||||
|
||||
metaStore->releaseDir(dirID);
|
||||
}
|
||||
|
||||
ctx.sendResponse(CreateEmptyContDirsRespMsg(&failedIDs) );
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
12
meta/source/net/message/fsck/CreateEmptyContDirsMsgEx.h
Normal file
12
meta/source/net/message/fsck/CreateEmptyContDirsMsgEx.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/storage/striping/Raid0Pattern.h>
|
||||
#include <common/net/message/fsck/CreateEmptyContDirsMsg.h>
|
||||
#include <common/net/message/fsck/CreateEmptyContDirsRespMsg.h>
|
||||
|
||||
class CreateEmptyContDirsMsgEx : public CreateEmptyContDirsMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
66
meta/source/net/message/fsck/DeleteDirEntriesMsgEx.cpp
Normal file
66
meta/source/net/message/fsck/DeleteDirEntriesMsgEx.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "DeleteDirEntriesMsgEx.h"
|
||||
|
||||
#include <program/Program.h>
|
||||
#include <common/fsck/FsckDirEntry.h>
|
||||
#include <toolkit/BuddyCommTk.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
bool DeleteDirEntriesMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("DeleteDirEntriesMsgEx");
|
||||
|
||||
MetaStore* metaStore = Program::getApp()->getMetaStore();
|
||||
EntryLockStore* entryLockStore = Program::getApp()->getMirroredSessions()->getEntryLockStore();
|
||||
|
||||
FsckDirEntryList& entries = getEntries();
|
||||
FsckDirEntryList failedEntries;
|
||||
|
||||
for ( FsckDirEntryListIter iter = entries.begin(); iter != entries.end(); iter++ )
|
||||
{
|
||||
const std::string& parentID = iter->getParentDirID();
|
||||
const std::string& entryName = iter->getName();
|
||||
FsckDirEntryType dirEntryType = iter->getEntryType();
|
||||
|
||||
FileIDLock dirLock;
|
||||
ParentNameLock dentryLock;
|
||||
|
||||
if (iter->getIsBuddyMirrored())
|
||||
{
|
||||
dirLock = {entryLockStore, parentID, true};
|
||||
dentryLock = {entryLockStore, parentID, entryName};
|
||||
}
|
||||
|
||||
DirInode* parentDirInode = metaStore->referenceDir(parentID, iter->getIsBuddyMirrored(),
|
||||
true);
|
||||
|
||||
if (!parentDirInode)
|
||||
{
|
||||
log.log(3,"Failed to delete directory entry; ParentID: " + parentID + "; EntryName: " +
|
||||
entryName + " - ParentID does not exist");
|
||||
failedEntries.push_back(*iter);
|
||||
continue;
|
||||
}
|
||||
|
||||
FhgfsOpsErr unlinkRes;
|
||||
|
||||
if (FsckDirEntryType_ISDIR(dirEntryType))
|
||||
unlinkRes = parentDirInode->removeDir(entryName, NULL);
|
||||
else
|
||||
unlinkRes = parentDirInode->unlinkDirEntry(entryName, NULL,
|
||||
DirEntry_UNLINK_ID_AND_FILENAME);
|
||||
|
||||
metaStore->releaseDir(parentID);
|
||||
|
||||
if (unlinkRes != FhgfsOpsErr_SUCCESS )
|
||||
{
|
||||
log.logErr("Failed to delete directory entry; ParentID: " + parentID + "; EntryName: " +
|
||||
entryName + "; Err: " + boost::lexical_cast<std::string>(unlinkRes));
|
||||
failedEntries.push_back(*iter);
|
||||
}
|
||||
}
|
||||
|
||||
ctx.sendResponse(DeleteDirEntriesRespMsg(&failedEntries) );
|
||||
|
||||
return true;
|
||||
}
|
||||
12
meta/source/net/message/fsck/DeleteDirEntriesMsgEx.h
Normal file
12
meta/source/net/message/fsck/DeleteDirEntriesMsgEx.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/net/message/fsck/DeleteDirEntriesMsg.h>
|
||||
#include <common/net/message/fsck/DeleteDirEntriesRespMsg.h>
|
||||
|
||||
class DeleteDirEntriesMsgEx : public DeleteDirEntriesMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
77
meta/source/net/message/fsck/FixInodeOwnersInDentryMsgEx.cpp
Normal file
77
meta/source/net/message/fsck/FixInodeOwnersInDentryMsgEx.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "FixInodeOwnersInDentryMsgEx.h"
|
||||
|
||||
#include <common/storage/striping/Raid0Pattern.h>
|
||||
#include <common/fsck/FsckDirEntry.h>
|
||||
#include <program/Program.h>
|
||||
#include <toolkit/BuddyCommTk.h>
|
||||
|
||||
bool FixInodeOwnersInDentryMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("FixInodeOwnersInDentryMsgEx");
|
||||
|
||||
MetaStore* metaStore = Program::getApp()->getMetaStore();
|
||||
EntryLockStore* entryLockStore = Program::getApp()->getMirroredSessions()->getEntryLockStore();
|
||||
|
||||
FsckDirEntryList& dentries = getDentries();
|
||||
FsckDirEntryList failedEntries;
|
||||
|
||||
FsckDirEntryListIter dentryIter = dentries.begin();
|
||||
NumNodeIDListIter ownerIter = getOwners().begin();
|
||||
|
||||
while (dentryIter != dentries.end() )
|
||||
{
|
||||
const std::string& parentID = dentryIter->getParentDirID();
|
||||
const std::string& entryName = dentryIter->getName();
|
||||
|
||||
ParentNameLock lock;
|
||||
|
||||
if (dentryIter->getIsBuddyMirrored())
|
||||
lock = {entryLockStore, parentID, entryName};
|
||||
|
||||
bool parentDirInodeIsTemp = false;
|
||||
DirInode* parentDirInode = metaStore->referenceDir(parentID,
|
||||
dentryIter->getIsBuddyMirrored(), true);
|
||||
|
||||
// it could be, that parentDirInode does not exist
|
||||
// in fsck we create a temporary inode for this case, so that we can modify the dentry
|
||||
// hopefully, the inode itself will get fixed later
|
||||
if (unlikely(!parentDirInode))
|
||||
{
|
||||
log.log(Log_NOTICE,
|
||||
"Failed to update directory entry. Parent directory could not be "
|
||||
"referenced. parentID: " + parentID + " entryName: " + entryName
|
||||
+ " => Using temporary inode");
|
||||
|
||||
// create temporary inode
|
||||
int mode = S_IFDIR | S_IRWXU;
|
||||
UInt16Vector stripeTargets;
|
||||
Raid0Pattern stripePattern(0, stripeTargets, 0);
|
||||
parentDirInode = new DirInode(parentID, mode, 0, 0,
|
||||
Program::getApp()->getLocalNode().getNumID(), stripePattern,
|
||||
dentryIter->getIsBuddyMirrored());
|
||||
|
||||
parentDirInodeIsTemp = true;
|
||||
}
|
||||
|
||||
FhgfsOpsErr updateRes = parentDirInode->setOwnerNodeID(entryName, *ownerIter);
|
||||
|
||||
if (updateRes != FhgfsOpsErr_SUCCESS )
|
||||
{
|
||||
log.log(Log_WARNING, "Failed to update directory entry. parentID: " + parentID +
|
||||
" entryName: " + entryName);
|
||||
failedEntries.push_back(*dentryIter);
|
||||
}
|
||||
|
||||
if (parentDirInodeIsTemp)
|
||||
SAFE_DELETE(parentDirInode);
|
||||
else
|
||||
metaStore->releaseDir(parentID);
|
||||
|
||||
dentryIter++;
|
||||
ownerIter++;
|
||||
}
|
||||
|
||||
ctx.sendResponse(FixInodeOwnersInDentryRespMsg(&failedEntries) );
|
||||
|
||||
return true;
|
||||
}
|
||||
12
meta/source/net/message/fsck/FixInodeOwnersInDentryMsgEx.h
Normal file
12
meta/source/net/message/fsck/FixInodeOwnersInDentryMsgEx.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/net/message/fsck/FixInodeOwnersInDentryMsg.h>
|
||||
#include <common/net/message/fsck/FixInodeOwnersInDentryRespMsg.h>
|
||||
|
||||
class FixInodeOwnersInDentryMsgEx : public FixInodeOwnersInDentryMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
51
meta/source/net/message/fsck/FixInodeOwnersMsgEx.cpp
Normal file
51
meta/source/net/message/fsck/FixInodeOwnersMsgEx.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "FixInodeOwnersMsgEx.h"
|
||||
|
||||
#include <common/fsck/FsckDirEntry.h>
|
||||
#include <program/Program.h>
|
||||
#include <toolkit/BuddyCommTk.h>
|
||||
|
||||
bool FixInodeOwnersMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
const char* logContext = "FixInodeOwnersMsgEx incoming";
|
||||
|
||||
MetaStore* metaStore = Program::getApp()->getMetaStore();
|
||||
EntryLockStore* entryLockStore = Program::getApp()->getMirroredSessions()->getEntryLockStore();
|
||||
|
||||
FsckDirInodeList& inodes = getInodes();
|
||||
FsckDirInodeList failedInodes;
|
||||
|
||||
for ( FsckDirInodeListIter iter = inodes.begin(); iter != inodes.end(); iter++ )
|
||||
{
|
||||
const std::string& entryID = iter->getID();
|
||||
NumNodeID ownerNodeID = iter->getOwnerNodeID();
|
||||
|
||||
FileIDLock lock;
|
||||
|
||||
if (iter->getIsBuddyMirrored())
|
||||
lock = {entryLockStore, entryID, true};
|
||||
|
||||
DirInode* dirInode = metaStore->referenceDir(entryID, iter->getIsBuddyMirrored(), true);
|
||||
|
||||
if (unlikely(!dirInode))
|
||||
{
|
||||
LogContext(logContext).log(Log_WARNING, "Failed to update directory inode. Inode could"
|
||||
" not be referenced. entryID: " + entryID);
|
||||
continue; // continue to next entry
|
||||
}
|
||||
|
||||
bool updateRes = dirInode->setOwnerNodeID(ownerNodeID);
|
||||
|
||||
metaStore->releaseDir(entryID);
|
||||
|
||||
if (!updateRes)
|
||||
{
|
||||
LogContext(logContext).log(Log_WARNING, "Failed to update directory inode. entryID: "
|
||||
+ entryID);
|
||||
failedInodes.push_back(*iter);
|
||||
}
|
||||
}
|
||||
|
||||
ctx.sendResponse(FixInodeOwnersRespMsg(&failedInodes) );
|
||||
|
||||
return true;
|
||||
}
|
||||
12
meta/source/net/message/fsck/FixInodeOwnersMsgEx.h
Normal file
12
meta/source/net/message/fsck/FixInodeOwnersMsgEx.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/net/message/fsck/FixInodeOwnersMsg.h>
|
||||
#include <common/net/message/fsck/FixInodeOwnersRespMsg.h>
|
||||
|
||||
class FixInodeOwnersMsgEx : public FixInodeOwnersMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
34
meta/source/net/message/fsck/FsckSetEventLoggingMsgEx.cpp
Normal file
34
meta/source/net/message/fsck/FsckSetEventLoggingMsgEx.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <components/ModificationEventFlusher.h>
|
||||
#include <program/Program.h>
|
||||
#include "FsckSetEventLoggingMsgEx.h"
|
||||
|
||||
bool FsckSetEventLoggingMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("FsckSetEventLoggingMsg incoming");
|
||||
|
||||
App* app = Program::getApp();
|
||||
ModificationEventFlusher* flusher = app->getModificationEventFlusher();
|
||||
|
||||
bool result;
|
||||
bool loggingEnabled;
|
||||
bool missedEvents;
|
||||
|
||||
bool enableLogging = this->getEnableLogging();
|
||||
|
||||
if (enableLogging)
|
||||
{
|
||||
loggingEnabled = flusher->enableLogging(getPortUDP(), getNicList(), getForceRestart());
|
||||
result = true; // (always true when logging is enabled)
|
||||
missedEvents = true; // (value ignored when logging is enabled)
|
||||
}
|
||||
else
|
||||
{ // disable logging
|
||||
result = flusher->disableLogging();
|
||||
loggingEnabled = false; // (value ignored when logging is disabled)
|
||||
missedEvents = flusher->getFsckMissedEvent();
|
||||
}
|
||||
|
||||
ctx.sendResponse(FsckSetEventLoggingRespMsg(result, loggingEnabled, missedEvents));
|
||||
|
||||
return true;
|
||||
}
|
||||
11
meta/source/net/message/fsck/FsckSetEventLoggingMsgEx.h
Normal file
11
meta/source/net/message/fsck/FsckSetEventLoggingMsgEx.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/fsck/FsckSetEventLoggingMsg.h>
|
||||
#include <common/net/message/fsck/FsckSetEventLoggingRespMsg.h>
|
||||
|
||||
class FsckSetEventLoggingMsgEx : public FsckSetEventLoggingMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
108
meta/source/net/message/fsck/LinkToLostAndFoundMsgEx.cpp
Normal file
108
meta/source/net/message/fsck/LinkToLostAndFoundMsgEx.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#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() );
|
||||
}
|
||||
}
|
||||
24
meta/source/net/message/fsck/LinkToLostAndFoundMsgEx.h
Normal file
24
meta/source/net/message/fsck/LinkToLostAndFoundMsgEx.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/net/message/fsck/LinkToLostAndFoundMsg.h>
|
||||
#include <common/net/message/fsck/LinkToLostAndFoundRespMsg.h>
|
||||
#include <common/net/message/storage/creating/MkDirMsg.h>
|
||||
#include <common/net/message/storage/creating/MkDirRespMsg.h>
|
||||
#include <common/storage/StorageErrors.h>
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
class LinkToLostAndFoundMsgEx : public LinkToLostAndFoundMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
|
||||
private:
|
||||
void linkDirInodes(FsckDirInodeList* outFailedInodes, FsckDirEntryList* outCreatedDirEntries);
|
||||
void linkFileInodes(FsckFileInodeList* outFailedInodes,
|
||||
FsckDirEntryList* outCreatedDirEntries);
|
||||
|
||||
FhgfsOpsErr deleteInode(std::string& entryID, uint16_t ownerNodeID);
|
||||
};
|
||||
|
||||
141
meta/source/net/message/fsck/RecreateDentriesMsgEx.cpp
Normal file
141
meta/source/net/message/fsck/RecreateDentriesMsgEx.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#include "RecreateDentriesMsgEx.h"
|
||||
|
||||
#include <common/fsck/FsckDirEntry.h>
|
||||
#include <common/fsck/FsckFsID.h>
|
||||
#include <program/Program.h>
|
||||
#include <toolkit/BuddyCommTk.h>
|
||||
|
||||
bool RecreateDentriesMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("RecreateDentriesMsgEx");
|
||||
|
||||
App* app = Program::getApp();
|
||||
MetaStore* metaStore = app->getMetaStore();
|
||||
|
||||
EntryLockStore* entryLockStore = app->getMirroredSessions()->getEntryLockStore();
|
||||
|
||||
FsckFsIDList& fsIDs = getFsIDs();
|
||||
FsckFsIDList failedCreates;
|
||||
FsckDirEntryList createdDentries;
|
||||
FsckFileInodeList createdInodes;
|
||||
|
||||
for ( FsckFsIDListIter iter = fsIDs.begin(); iter != fsIDs.end(); iter++ )
|
||||
{
|
||||
NumNodeID localNodeID = iter->getIsBuddyMirrored()
|
||||
? NumNodeID(app->getMetaBuddyGroupMapper()->getLocalGroupID())
|
||||
: app->getLocalNodeNumID();
|
||||
|
||||
std::string parentPath = MetaStorageTk::getMetaDirEntryPath(
|
||||
iter->getIsBuddyMirrored()
|
||||
? app->getBuddyMirrorDentriesPath()->str()
|
||||
: app->getDentriesPath()->str(), iter->getParentDirID());
|
||||
|
||||
std::string dirEntryIDFilePath = MetaStorageTk::getMetaDirEntryIDPath(parentPath) + "/"
|
||||
+ iter->getID();
|
||||
|
||||
// the name is lost, so we take the ID as new name
|
||||
std::string dirEntryNameFilePath = parentPath + "/" + iter->getID();
|
||||
|
||||
// before we link, let's see if we can open the parent dir, otherwise we should not mess
|
||||
// around here
|
||||
const std::string& dirID = iter->getParentDirID();
|
||||
|
||||
FileIDLock dirLock;
|
||||
ParentNameLock dentryLock;
|
||||
|
||||
if (iter->getIsBuddyMirrored())
|
||||
{
|
||||
dirLock = {entryLockStore, dirID, true};
|
||||
dentryLock = {entryLockStore, dirID, iter->getID()};
|
||||
}
|
||||
|
||||
DirInode* parentDirInode = metaStore->referenceDir(dirID, iter->getIsBuddyMirrored(), false);
|
||||
|
||||
if (!parentDirInode)
|
||||
{
|
||||
log.logErr("Unable to reference parent directory; ID: " + iter->getParentDirID());
|
||||
failedCreates.push_back(*iter);
|
||||
continue;
|
||||
}
|
||||
|
||||
// link the dentry-by-name file
|
||||
int linkRes = link(dirEntryIDFilePath.c_str(), dirEntryNameFilePath.c_str());
|
||||
|
||||
if ( linkRes )
|
||||
{
|
||||
// error occured while linking
|
||||
log.logErr(
|
||||
"Failed to link dentry file; ParentID: " + iter->getParentDirID() + "; ID: "
|
||||
+ iter->getID());
|
||||
failedCreates.push_back(*iter);
|
||||
|
||||
metaStore->releaseDir(dirID);
|
||||
continue;
|
||||
}
|
||||
|
||||
// linking was OK => gather dentry (and inode) data, so fsck can add it
|
||||
|
||||
DirEntry dirEntry(iter->getID());
|
||||
bool getRes = parentDirInode->getDentry(iter->getID(), dirEntry);
|
||||
|
||||
if (!getRes)
|
||||
{
|
||||
log.logErr(
|
||||
"Could not read the created dentry file; ParentID: " + iter->getParentDirID() + "; ID: "
|
||||
+ iter->getID());
|
||||
failedCreates.push_back(*iter);
|
||||
|
||||
metaStore->releaseDir(dirID);
|
||||
continue;
|
||||
}
|
||||
|
||||
// create the FsckDirEntry
|
||||
FsckDirEntry fsckDirEntry(dirEntry.getID(), dirEntry.getName(), iter->getParentDirID(),
|
||||
localNodeID, localNodeID,
|
||||
FsckTk::DirEntryTypeToFsckDirEntryType(dirEntry.getEntryType()), true, localNodeID,
|
||||
iter->getSaveDevice(), iter->getSaveInode(), iter->getIsBuddyMirrored());
|
||||
createdDentries.push_back(fsckDirEntry);
|
||||
|
||||
// inlined inode data should be present, because otherwise dentry-by-id file would not
|
||||
// exist, and we could not get this far
|
||||
FileInodeStoreData* inodeData = dirEntry.getInodeStoreData();
|
||||
|
||||
if ( inodeData )
|
||||
{
|
||||
int pathInfoFlags;
|
||||
|
||||
if (inodeData->getOrigFeature() == FileInodeOrigFeature_TRUE)
|
||||
pathInfoFlags = PATHINFO_FEATURE_ORIG;
|
||||
else
|
||||
pathInfoFlags = PATHINFO_FEATURE_ORIG_UNKNOWN;
|
||||
|
||||
PathInfo pathInfo(inodeData->getOrigUID(), inodeData->getOrigParentEntryID(),
|
||||
pathInfoFlags);
|
||||
|
||||
UInt16Vector targetIDs;
|
||||
unsigned chunkSize;
|
||||
FsckStripePatternType fsckStripePatternType = FsckTk::stripePatternToFsckStripePattern(
|
||||
inodeData->getPattern(), &chunkSize, &targetIDs);
|
||||
|
||||
FsckFileInode fsckFileInode(inodeData->getEntryID(), iter->getParentDirID(),
|
||||
localNodeID, pathInfo, inodeData->getInodeStatData(),
|
||||
inodeData->getInodeStatData()->getNumBlocks(), targetIDs, fsckStripePatternType,
|
||||
chunkSize, localNodeID, iter->getSaveInode(), iter->getSaveDevice(), true,
|
||||
iter->getIsBuddyMirrored(), true, false);
|
||||
|
||||
createdInodes.push_back(fsckFileInode);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.logErr(
|
||||
"No inlined inode data found; parentID: " + iter->getParentDirID() + "; ID: "
|
||||
+ iter->getID());
|
||||
}
|
||||
|
||||
metaStore->releaseDir(dirID);
|
||||
}
|
||||
|
||||
ctx.sendResponse(RecreateDentriesRespMsg(&failedCreates, &createdDentries, &createdInodes) );
|
||||
|
||||
return true;
|
||||
}
|
||||
12
meta/source/net/message/fsck/RecreateDentriesMsgEx.h
Normal file
12
meta/source/net/message/fsck/RecreateDentriesMsgEx.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/net/message/fsck/RecreateDentriesMsg.h>
|
||||
#include <common/net/message/fsck/RecreateDentriesRespMsg.h>
|
||||
|
||||
class RecreateDentriesMsgEx : public RecreateDentriesMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
65
meta/source/net/message/fsck/RecreateFsIDsMsgEx.cpp
Normal file
65
meta/source/net/message/fsck/RecreateFsIDsMsgEx.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "RecreateFsIDsMsgEx.h"
|
||||
|
||||
#include <common/fsck/FsckDirEntry.h>
|
||||
#include <program/Program.h>
|
||||
#include <toolkit/BuddyCommTk.h>
|
||||
|
||||
bool RecreateFsIDsMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
EntryLockStore* entryLockStore = Program::getApp()->getMirroredSessions()->getEntryLockStore();
|
||||
|
||||
LogContext log("RecreateFsIDsMsgEx");
|
||||
|
||||
FsckDirEntryList& entries = getEntries();
|
||||
FsckDirEntryList failedEntries;
|
||||
|
||||
for ( FsckDirEntryListIter iter = entries.begin(); iter != entries.end(); iter++ )
|
||||
{
|
||||
const std::string& parentID = iter->getParentDirID();
|
||||
const std::string& entryName = iter->getName();
|
||||
const std::string& entryID = iter->getID();
|
||||
|
||||
std::string dirEntryPath = MetaStorageTk::getMetaDirEntryPath(
|
||||
iter->getIsBuddyMirrored()
|
||||
? Program::getApp()->getBuddyMirrorDentriesPath()->str()
|
||||
: Program::getApp()->getDentriesPath()->str(), parentID);
|
||||
|
||||
std::string dirEntryIDFilePath = MetaStorageTk::getMetaDirEntryIDPath(dirEntryPath) +
|
||||
"/" + entryID;
|
||||
|
||||
std::string dirEntryNameFilePath = dirEntryPath + "/" + entryName;
|
||||
|
||||
FileIDLock dirLock(entryLockStore, parentID, true);
|
||||
ParentNameLock dentryLock(entryLockStore, parentID, entryName);
|
||||
FileIDLock fileLock(entryLockStore, entryID, true);
|
||||
|
||||
// delete the old dentry-by-id file link (if one existed)
|
||||
int removeRes = unlink(dirEntryIDFilePath.c_str());
|
||||
|
||||
if ( (removeRes) && (errno != ENOENT) )
|
||||
{
|
||||
log.logErr(
|
||||
"Failed to recreate dentry-by-id file for directory entry; ParentID: " + parentID
|
||||
+ "; EntryName: " + entryName
|
||||
+ " - Could not delete old, faulty dentry-by-id file link");
|
||||
failedEntries.push_back(*iter);
|
||||
continue;
|
||||
}
|
||||
|
||||
// link a new one
|
||||
int linkRes = link(dirEntryNameFilePath.c_str(), dirEntryIDFilePath.c_str());
|
||||
|
||||
if ( linkRes )
|
||||
{
|
||||
log.logErr(
|
||||
"Failed to recreate dentry-by-id file for directory entry; ParentID: " + parentID
|
||||
+ "; EntryName: " + entryName + " - File could not be linked");
|
||||
failedEntries.push_back(*iter);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.sendResponse(RecreateFsIDsRespMsg(&failedEntries) );
|
||||
|
||||
return true;
|
||||
}
|
||||
12
meta/source/net/message/fsck/RecreateFsIDsMsgEx.h
Normal file
12
meta/source/net/message/fsck/RecreateFsIDsMsgEx.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/net/message/fsck/RecreateFsIDsMsg.h>
|
||||
#include <common/net/message/fsck/RecreateFsIDsRespMsg.h>
|
||||
|
||||
class RecreateFsIDsMsgEx : public RecreateFsIDsMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
44
meta/source/net/message/fsck/RemoveInodesMsgEx.cpp
Normal file
44
meta/source/net/message/fsck/RemoveInodesMsgEx.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <program/Program.h>
|
||||
#include <common/net/message/fsck/RemoveInodesRespMsg.h>
|
||||
#include <common/toolkit/ZipIterator.h>
|
||||
#include <toolkit/BuddyCommTk.h>
|
||||
|
||||
#include "RemoveInodesMsgEx.h"
|
||||
|
||||
|
||||
bool RemoveInodesMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
MetaStore* metaStore = Program::getApp()->getMetaStore();
|
||||
EntryLockStore* entryLockStore = Program::getApp()->getMirroredSessions()->getEntryLockStore();
|
||||
|
||||
StringList failedIDList;
|
||||
|
||||
for (auto it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
const std::string& entryID = std::get<0>(*it);
|
||||
const DirEntryType entryType = std::get<1>(*it);
|
||||
const bool isBuddyMirrored = std::get<2>(*it);
|
||||
FhgfsOpsErr rmRes;
|
||||
|
||||
FileIDLock dirLock;
|
||||
FileIDLock fileLock;
|
||||
|
||||
if (entryType == DirEntryType_DIRECTORY)
|
||||
{
|
||||
dirLock = {entryLockStore, entryID, true};
|
||||
rmRes = metaStore->removeDirInode(entryID, isBuddyMirrored);
|
||||
}
|
||||
else
|
||||
{
|
||||
fileLock = {entryLockStore, entryID, true};
|
||||
rmRes = metaStore->fsckUnlinkFileInode(entryID, isBuddyMirrored);
|
||||
}
|
||||
|
||||
if (rmRes != FhgfsOpsErr_SUCCESS)
|
||||
failedIDList.push_back(entryID);
|
||||
}
|
||||
|
||||
ctx.sendResponse(RemoveInodesRespMsg(std::move(failedIDList)));
|
||||
|
||||
return true;
|
||||
}
|
||||
10
meta/source/net/message/fsck/RemoveInodesMsgEx.h
Normal file
10
meta/source/net/message/fsck/RemoveInodesMsgEx.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/fsck/RemoveInodesMsg.h>
|
||||
|
||||
class RemoveInodesMsgEx : public RemoveInodesMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
269
meta/source/net/message/fsck/RetrieveDirEntriesMsgEx.cpp
Normal file
269
meta/source/net/message/fsck/RetrieveDirEntriesMsgEx.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
#include "RetrieveDirEntriesMsgEx.h"
|
||||
|
||||
#include <common/storage/striping/Raid0Pattern.h>
|
||||
#include <net/msghelpers/MsgHelperStat.h>
|
||||
#include <program/Program.h>
|
||||
|
||||
bool RetrieveDirEntriesMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("Incoming RetrieveDirEntriesMsg");
|
||||
|
||||
unsigned hashDirNum = getHashDirNum();
|
||||
std::string currentContDirID = getCurrentContDirID();
|
||||
unsigned maxOutEntries = getMaxOutEntries();
|
||||
|
||||
int64_t lastContDirOffset = getLastContDirOffset();
|
||||
int64_t lastHashDirOffset = getLastHashDirOffset();
|
||||
int64_t newHashDirOffset;
|
||||
int64_t newContDirOffset;
|
||||
|
||||
FsckContDirList contDirsOutgoing;
|
||||
FsckDirEntryList dirEntriesOutgoing;
|
||||
FsckFileInodeList inlinedFileInodesOutgoing;
|
||||
|
||||
unsigned readOutEntries = 0;
|
||||
|
||||
NumNodeID localNodeNumID = getIsBuddyMirrored()
|
||||
? NumNodeID(Program::getApp()->getMetaBuddyGroupMapper()->getLocalGroupID())
|
||||
: Program::getApp()->getLocalNode().getNumID();
|
||||
MetaStore* metaStore = Program::getApp()->getMetaStore();
|
||||
MirrorBuddyGroupMapper* bgm = Program::getApp()->getMetaBuddyGroupMapper();
|
||||
|
||||
if (getIsBuddyMirrored() &&
|
||||
(bgm->getLocalBuddyGroup().secondTargetID
|
||||
== Program::getApp()->getLocalNode().getNumID().val()
|
||||
|| bgm->getLocalGroupID() == 0))
|
||||
{
|
||||
ctx.sendResponse(
|
||||
RetrieveDirEntriesRespMsg(&contDirsOutgoing, &dirEntriesOutgoing,
|
||||
&inlinedFileInodesOutgoing, currentContDirID, lastHashDirOffset, lastContDirOffset));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hasNext;
|
||||
|
||||
if ( currentContDirID.empty() )
|
||||
{
|
||||
hasNext = StorageTkEx::getNextContDirID(hashDirNum, getIsBuddyMirrored(), lastHashDirOffset,
|
||||
¤tContDirID, &newHashDirOffset);
|
||||
if ( hasNext )
|
||||
{
|
||||
lastHashDirOffset = newHashDirOffset;
|
||||
// we found a new .cont directory => send it to fsck
|
||||
FsckContDir contDir(currentContDirID, localNodeNumID, getIsBuddyMirrored());
|
||||
contDirsOutgoing.push_back(contDir);
|
||||
}
|
||||
}
|
||||
else
|
||||
hasNext = true;
|
||||
|
||||
while ( hasNext )
|
||||
{
|
||||
std::string parentID = currentContDirID;
|
||||
|
||||
unsigned remainingOutNames = maxOutEntries - readOutEntries;
|
||||
StringList entryNames;
|
||||
|
||||
bool parentDirInodeIsTemp = false;
|
||||
DirInode* parentDirInode = metaStore->referenceDir(parentID, getIsBuddyMirrored(), true);
|
||||
|
||||
// it could be, that parentDirInode does not exist
|
||||
// in fsck we create a temporary inode for this case, so that we can modify the dentry
|
||||
// hopefully, the inode itself will get fixed later
|
||||
if ( unlikely(!parentDirInode) )
|
||||
{
|
||||
log.log(
|
||||
Log_NOTICE,
|
||||
"Could not reference directory. EntryID: " + parentID
|
||||
+ " => using temporary directory inode ");
|
||||
|
||||
// create temporary inode
|
||||
int mode = S_IFDIR | S_IRWXU;
|
||||
UInt16Vector stripeTargets;
|
||||
Raid0Pattern stripePattern(0, stripeTargets, 0);
|
||||
parentDirInode = new DirInode(parentID, mode, 0, 0,
|
||||
Program::getApp()->getLocalNode().getNumID(), stripePattern, getIsBuddyMirrored());
|
||||
|
||||
parentDirInodeIsTemp = true;
|
||||
}
|
||||
|
||||
if ( parentDirInode->listIncremental(lastContDirOffset, remainingOutNames, &entryNames,
|
||||
&newContDirOffset) == FhgfsOpsErr_SUCCESS )
|
||||
{
|
||||
lastContDirOffset = newContDirOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.log(Log_WARNING, "Could not list contents of directory. EntryID: " + parentID);
|
||||
}
|
||||
|
||||
// actually process the entries
|
||||
for ( StringListIter namesIter = entryNames.begin(); namesIter != entryNames.end();
|
||||
namesIter++ )
|
||||
{
|
||||
std::string filename = MetaStorageTk::getMetaDirEntryPath(
|
||||
getIsBuddyMirrored()
|
||||
? Program::getApp()->getBuddyMirrorDentriesPath()->str()
|
||||
: Program::getApp()->getDentriesPath()->str(), parentID) + "/" + *namesIter;
|
||||
|
||||
// create a EntryInfo and put the information into an FsckDirEntry object
|
||||
EntryInfo entryInfo;
|
||||
FileInodeStoreData inodeDiskData;
|
||||
bool hasInlinedInode = false;
|
||||
|
||||
int32_t saveDevice = 0;
|
||||
uint64_t saveInode = 0;
|
||||
|
||||
auto [getEntryRes, isFileOpen] = metaStore->getEntryData(parentDirInode, *namesIter, &entryInfo,
|
||||
&inodeDiskData);
|
||||
|
||||
if (getEntryRes == FhgfsOpsErr_SUCCESS ||
|
||||
getEntryRes == FhgfsOpsErr_DYNAMICATTRIBSOUTDATED )
|
||||
{
|
||||
DirEntryType entryType = entryInfo.getEntryType();
|
||||
|
||||
const std::string& dentryID = entryInfo.getEntryID();
|
||||
const std::string& dentryName = *namesIter;
|
||||
NumNodeID dentryOwnerID = entryInfo.getOwnerNodeID();
|
||||
FsckDirEntryType fsckEntryType = FsckTk::DirEntryTypeToFsckDirEntryType(entryType);
|
||||
|
||||
// stat the file to get device and inode information
|
||||
struct stat statBuf;
|
||||
|
||||
int statRes = stat(filename.c_str(), &statBuf);
|
||||
|
||||
if (likely(!statRes))
|
||||
{
|
||||
saveDevice = statBuf.st_dev;
|
||||
saveInode = statBuf.st_ino;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.log(Log_CRITICAL, "Could not stat dir entry file; entryID: " + dentryID
|
||||
+ ";filename: " + filename);
|
||||
}
|
||||
|
||||
if ( (DirEntryType_ISFILE(entryType)) && (entryInfo.getIsInlined() ) )
|
||||
{
|
||||
hasInlinedInode = true;
|
||||
}
|
||||
|
||||
FsckDirEntry fsckDirEntry(dentryID, dentryName, parentID, localNodeNumID,
|
||||
dentryOwnerID, fsckEntryType, hasInlinedInode, localNodeNumID,
|
||||
saveDevice, saveInode, entryInfo.getIsBuddyMirrored());
|
||||
|
||||
dirEntriesOutgoing.push_back(fsckDirEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.log(Log_WARNING, "Unable to create dir entry from entry with name " + *namesIter
|
||||
+ " in directory with ID " + parentID);
|
||||
}
|
||||
|
||||
// now, if the inode data is inlined we create an fsck inode object here
|
||||
if ( hasInlinedInode )
|
||||
{
|
||||
std::string inodeID = inodeDiskData.getEntryID();
|
||||
|
||||
int pathInfoFlag;
|
||||
if (inodeDiskData.getOrigFeature() == FileInodeOrigFeature_TRUE)
|
||||
pathInfoFlag = PATHINFO_FEATURE_ORIG;
|
||||
else
|
||||
pathInfoFlag = PATHINFO_FEATURE_ORIG_UNKNOWN;
|
||||
|
||||
unsigned origUID = inodeDiskData.getOrigUID();
|
||||
std::string origParentEntryID = inodeDiskData.getOrigParentEntryID();
|
||||
PathInfo pathInfo(origUID, origParentEntryID, pathInfoFlag);
|
||||
|
||||
unsigned userID;
|
||||
unsigned groupID;
|
||||
|
||||
int64_t fileSize;
|
||||
unsigned numHardLinks;
|
||||
uint64_t numBlocks;
|
||||
|
||||
StatData* statData;
|
||||
StatData updatedStatData;
|
||||
|
||||
if (getEntryRes == FhgfsOpsErr_SUCCESS)
|
||||
statData = inodeDiskData.getInodeStatData();
|
||||
else
|
||||
{
|
||||
FhgfsOpsErr statRes = MsgHelperStat::stat(&entryInfo, true, getMsgHeaderUserID(),
|
||||
updatedStatData);
|
||||
|
||||
if (statRes == FhgfsOpsErr_SUCCESS)
|
||||
statData = &updatedStatData;
|
||||
else
|
||||
statData = NULL;
|
||||
}
|
||||
|
||||
if ( statData )
|
||||
{
|
||||
userID = statData->getUserID();
|
||||
groupID = statData->getGroupID();
|
||||
fileSize = statData->getFileSize();
|
||||
numHardLinks = statData->getNumHardlinks();
|
||||
numBlocks = statData->getNumBlocks();
|
||||
}
|
||||
else
|
||||
{
|
||||
log.logErr(std::string("Unable to get stat data of inlined file inode: ") + inodeID
|
||||
+ ". SysErr: " + System::getErrString());
|
||||
userID = 0;
|
||||
groupID = 0;
|
||||
fileSize = 0;
|
||||
numHardLinks = 0;
|
||||
numBlocks = 0;
|
||||
}
|
||||
|
||||
UInt16Vector stripeTargets;
|
||||
unsigned chunkSize;
|
||||
FsckStripePatternType stripePatternType = FsckTk::stripePatternToFsckStripePattern(
|
||||
inodeDiskData.getPattern(), &chunkSize, &stripeTargets);
|
||||
|
||||
FsckFileInode fileInode(inodeID, parentID, localNodeNumID, pathInfo, userID, groupID,
|
||||
fileSize, numHardLinks, numBlocks, stripeTargets, stripePatternType, chunkSize,
|
||||
localNodeNumID, saveInode, saveDevice, true, entryInfo.getIsBuddyMirrored(),
|
||||
true, inodeDiskData.getIsBuddyMirrored() != getIsBuddyMirrored());
|
||||
|
||||
inlinedFileInodesOutgoing.push_back(fileInode);
|
||||
}
|
||||
}
|
||||
|
||||
if ( parentDirInodeIsTemp )
|
||||
SAFE_DELETE(parentDirInode);
|
||||
else
|
||||
metaStore->releaseDir(parentID);
|
||||
|
||||
if ( entryNames.size() < remainingOutNames )
|
||||
{
|
||||
// directory is at the end => proceed with next
|
||||
hasNext = StorageTkEx::getNextContDirID(hashDirNum, getIsBuddyMirrored(),
|
||||
lastHashDirOffset, ¤tContDirID, &newHashDirOffset);
|
||||
|
||||
if ( hasNext )
|
||||
{
|
||||
lastHashDirOffset = newHashDirOffset;
|
||||
lastContDirOffset = 0;
|
||||
|
||||
readOutEntries += entryNames.size();
|
||||
|
||||
// we found a new .cont directory => send it to fsck
|
||||
FsckContDir contDir(currentContDirID, localNodeNumID, getIsBuddyMirrored());
|
||||
contDirsOutgoing.push_back(contDir);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// there are more to come, but we need to exit the loop now, because maxCount is reached
|
||||
hasNext = false;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.sendResponse(
|
||||
RetrieveDirEntriesRespMsg(&contDirsOutgoing, &dirEntriesOutgoing,
|
||||
&inlinedFileInodesOutgoing, currentContDirID, lastHashDirOffset, lastContDirOffset) );
|
||||
|
||||
return true;
|
||||
}
|
||||
11
meta/source/net/message/fsck/RetrieveDirEntriesMsgEx.h
Normal file
11
meta/source/net/message/fsck/RetrieveDirEntriesMsgEx.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/fsck/RetrieveDirEntriesMsg.h>
|
||||
#include <common/net/message/fsck/RetrieveDirEntriesRespMsg.h>
|
||||
|
||||
class RetrieveDirEntriesMsgEx : public RetrieveDirEntriesMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
166
meta/source/net/message/fsck/RetrieveFsIDsMsgEx.cpp
Normal file
166
meta/source/net/message/fsck/RetrieveFsIDsMsgEx.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
#include "RetrieveFsIDsMsgEx.h"
|
||||
|
||||
#include <common/storage/striping/Raid0Pattern.h>
|
||||
#include <common/threading/SafeRWLock.h>
|
||||
#include <program/Program.h>
|
||||
|
||||
bool RetrieveFsIDsMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("Incoming RetrieveFsIDsMsg");
|
||||
|
||||
App* app = Program::getApp();
|
||||
MetaStore* metaStore = app->getMetaStore();
|
||||
|
||||
unsigned hashDirNum = getHashDirNum();
|
||||
bool buddyMirrored = getBuddyMirrored();
|
||||
std::string currentContDirID = getCurrentContDirID();
|
||||
unsigned maxOutIDs = getMaxOutIDs();
|
||||
|
||||
int64_t lastContDirOffset = getLastContDirOffset();
|
||||
int64_t lastHashDirOffset = getLastHashDirOffset();
|
||||
int64_t newHashDirOffset;
|
||||
|
||||
FsckFsIDList fsIDsOutgoing;
|
||||
|
||||
unsigned readOutIDs = 0;
|
||||
|
||||
NumNodeID localNodeNumID = buddyMirrored
|
||||
? NumNodeID(Program::getApp()->getMetaBuddyGroupMapper()->getLocalGroupID())
|
||||
: Program::getApp()->getLocalNode().getNumID();
|
||||
MirrorBuddyGroupMapper* bgm = Program::getApp()->getMetaBuddyGroupMapper();
|
||||
|
||||
if (buddyMirrored &&
|
||||
(bgm->getLocalBuddyGroup().secondTargetID == app->getLocalNode().getNumID().val()
|
||||
|| bgm->getLocalGroupID() == 0))
|
||||
{
|
||||
ctx.sendResponse(
|
||||
RetrieveFsIDsRespMsg(&fsIDsOutgoing, currentContDirID, lastHashDirOffset,
|
||||
lastContDirOffset));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hasNext;
|
||||
|
||||
if ( currentContDirID.empty() )
|
||||
{
|
||||
hasNext = StorageTkEx::getNextContDirID(hashDirNum, buddyMirrored, lastHashDirOffset,
|
||||
¤tContDirID, &newHashDirOffset);
|
||||
if ( hasNext )
|
||||
lastHashDirOffset = newHashDirOffset;
|
||||
}
|
||||
else
|
||||
hasNext = true;
|
||||
|
||||
while ( hasNext )
|
||||
{
|
||||
std::string parentID = currentContDirID;
|
||||
std::string idPath = MetaStorageTk::getMetaDirEntryIDPath(
|
||||
MetaStorageTk::getMetaDirEntryPath(
|
||||
buddyMirrored
|
||||
? app->getBuddyMirrorDentriesPath()->str()
|
||||
: app->getDentriesPath()->str(),
|
||||
parentID));
|
||||
|
||||
bool parentDirInodeIsTemp = false;
|
||||
StringList outNames;
|
||||
int64_t outNewServerOffset;
|
||||
ListIncExOutArgs outArgs(&outNames, NULL, NULL, NULL, &outNewServerOffset);
|
||||
|
||||
FhgfsOpsErr listRes;
|
||||
|
||||
unsigned remainingOutIDs = maxOutIDs - readOutIDs;
|
||||
|
||||
DirInode* parentDirInode = metaStore->referenceDir(parentID, buddyMirrored, true);
|
||||
|
||||
// it could be, that parentDirInode does not exist
|
||||
// in fsck we create a temporary inode for this case, so that we can modify the dentry
|
||||
// hopefully, the inode itself will get fixed later
|
||||
if ( unlikely(!parentDirInode) )
|
||||
{
|
||||
log.log(
|
||||
Log_NOTICE,
|
||||
"Could not reference directory. EntryID: " + parentID
|
||||
+ " => using temporary directory inode ");
|
||||
|
||||
// create temporary inode
|
||||
int mode = S_IFDIR | S_IRWXU;
|
||||
UInt16Vector stripeTargets;
|
||||
Raid0Pattern stripePattern(0, stripeTargets, 0);
|
||||
parentDirInode = new DirInode(parentID, mode, 0, 0,
|
||||
Program::getApp()->getLocalNode().getNumID(), stripePattern, buddyMirrored);
|
||||
|
||||
parentDirInodeIsTemp = true;
|
||||
}
|
||||
|
||||
listRes = parentDirInode->listIDFilesIncremental(lastContDirOffset, 0, remainingOutIDs,
|
||||
outArgs);
|
||||
|
||||
lastContDirOffset = outNewServerOffset;
|
||||
|
||||
if ( parentDirInodeIsTemp )
|
||||
SAFE_DELETE(parentDirInode);
|
||||
else
|
||||
metaStore->releaseDir(parentID);
|
||||
|
||||
if (listRes != FhgfsOpsErr_SUCCESS)
|
||||
{
|
||||
log.logErr("Could not read dentry-by-ID files; parentID: " + parentID);
|
||||
}
|
||||
|
||||
// process entries
|
||||
readOutIDs += outNames.size();
|
||||
|
||||
for ( StringListIter iter = outNames.begin(); iter != outNames.end(); iter++ )
|
||||
{
|
||||
std::string id = *iter;
|
||||
std::string filename = idPath + "/" + id;
|
||||
|
||||
// stat the file to get device and inode information
|
||||
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;
|
||||
log.log(Log_CRITICAL,
|
||||
"Could not stat ID file; ID: " + id + ";filename: " + filename);
|
||||
}
|
||||
|
||||
FsckFsID fsID(id, parentID, localNodeNumID, saveDevice, saveInode, buddyMirrored);
|
||||
fsIDsOutgoing.push_back(fsID);
|
||||
}
|
||||
|
||||
if ( readOutIDs < maxOutIDs )
|
||||
{
|
||||
// directory is at the end => proceed with next
|
||||
hasNext = StorageTkEx::getNextContDirID(hashDirNum, buddyMirrored, lastHashDirOffset,
|
||||
¤tContDirID, &newHashDirOffset);
|
||||
|
||||
if ( hasNext )
|
||||
{
|
||||
lastHashDirOffset = newHashDirOffset;
|
||||
lastContDirOffset = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// there are more to come, but we need to exit the loop now, because maxCount is reached
|
||||
hasNext = false;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.sendResponse(
|
||||
RetrieveFsIDsRespMsg(&fsIDsOutgoing, currentContDirID, lastHashDirOffset,
|
||||
lastContDirOffset) );
|
||||
|
||||
return true;
|
||||
}
|
||||
11
meta/source/net/message/fsck/RetrieveFsIDsMsgEx.h
Normal file
11
meta/source/net/message/fsck/RetrieveFsIDsMsgEx.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/fsck/RetrieveFsIDsMsg.h>
|
||||
#include <common/net/message/fsck/RetrieveFsIDsRespMsg.h>
|
||||
|
||||
class RetrieveFsIDsMsgEx : public RetrieveFsIDsMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
25
meta/source/net/message/fsck/RetrieveInodesMsgEx.cpp
Normal file
25
meta/source/net/message/fsck/RetrieveInodesMsgEx.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "RetrieveInodesMsgEx.h"
|
||||
|
||||
#include <program/Program.h>
|
||||
|
||||
bool RetrieveInodesMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("Incoming RetrieveInodesMsg");
|
||||
|
||||
MetaStore *metaStore = Program::getApp()->getMetaStore();
|
||||
|
||||
unsigned hashDirNum = getHashDirNum();
|
||||
unsigned maxOutInodes = getMaxOutInodes();
|
||||
int64_t lastOffset = getLastOffset();
|
||||
int64_t newOffset;
|
||||
|
||||
FsckFileInodeList fileInodesOutgoing;
|
||||
FsckDirInodeList dirInodesOutgoing;
|
||||
|
||||
metaStore->getAllInodesIncremental(hashDirNum, lastOffset, maxOutInodes, &dirInodesOutgoing,
|
||||
&fileInodesOutgoing, &newOffset, getIsBuddyMirrored());
|
||||
|
||||
ctx.sendResponse(RetrieveInodesRespMsg(&fileInodesOutgoing, &dirInodesOutgoing, newOffset) );
|
||||
|
||||
return true;
|
||||
}
|
||||
11
meta/source/net/message/fsck/RetrieveInodesMsgEx.h
Normal file
11
meta/source/net/message/fsck/RetrieveInodesMsgEx.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/fsck/RetrieveInodesMsg.h>
|
||||
#include <common/net/message/fsck/RetrieveInodesRespMsg.h>
|
||||
|
||||
class RetrieveInodesMsgEx : public RetrieveInodesMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
51
meta/source/net/message/fsck/UpdateDirAttribsMsgEx.cpp
Normal file
51
meta/source/net/message/fsck/UpdateDirAttribsMsgEx.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "UpdateDirAttribsMsgEx.h"
|
||||
|
||||
#include <storage/MetaStore.h>
|
||||
#include <program/Program.h>
|
||||
#include <toolkit/BuddyCommTk.h>
|
||||
|
||||
bool UpdateDirAttribsMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
const char* logContext = "UpdateDirAttribsMsg incoming";
|
||||
|
||||
MetaStore* metaStore = Program::getApp()->getMetaStore();
|
||||
EntryLockStore* entryLockStore = Program::getApp()->getMirroredSessions()->getEntryLockStore();
|
||||
|
||||
FsckDirInodeList& inodes = getInodes();
|
||||
FsckDirInodeList failedInodes;
|
||||
|
||||
for (FsckDirInodeListIter iter = inodes.begin(); iter != inodes.end(); iter++)
|
||||
{
|
||||
// call the updating method
|
||||
const std::string& dirID = iter->getID();
|
||||
|
||||
FileIDLock lock;
|
||||
|
||||
if (iter->getIsBuddyMirrored())
|
||||
lock = {entryLockStore, dirID, true};
|
||||
|
||||
DirInode* dirInode = metaStore->referenceDir(dirID, iter->getIsBuddyMirrored(), true);
|
||||
|
||||
if (!dirInode)
|
||||
{
|
||||
LogContext(logContext).logErr("Unable to reference directory; ID: " + dirID);
|
||||
failedInodes.push_back(*iter);
|
||||
continue;
|
||||
}
|
||||
|
||||
FhgfsOpsErr refreshRes = dirInode->refreshMetaInfo();
|
||||
|
||||
metaStore->releaseDir(dirID);
|
||||
|
||||
if (refreshRes != FhgfsOpsErr_SUCCESS)
|
||||
{
|
||||
LogContext(logContext).log(Log_WARNING, "Failed to update attributes of directory. "
|
||||
"entryID: " + dirID);
|
||||
failedInodes.push_back(*iter);
|
||||
}
|
||||
}
|
||||
|
||||
ctx.sendResponse(UpdateDirAttribsRespMsg(&failedInodes) );
|
||||
|
||||
return true;
|
||||
}
|
||||
12
meta/source/net/message/fsck/UpdateDirAttribsMsgEx.h
Normal file
12
meta/source/net/message/fsck/UpdateDirAttribsMsgEx.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/net/message/fsck/UpdateDirAttribsMsg.h>
|
||||
#include <common/net/message/fsck/UpdateDirAttribsRespMsg.h>
|
||||
|
||||
class UpdateDirAttribsMsgEx : public UpdateDirAttribsMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
62
meta/source/net/message/fsck/UpdateFileAttribsMsgEx.cpp
Normal file
62
meta/source/net/message/fsck/UpdateFileAttribsMsgEx.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "UpdateFileAttribsMsgEx.h"
|
||||
|
||||
#include <net/msghelpers/MsgHelperStat.h>
|
||||
#include <program/Program.h>
|
||||
#include <toolkit/BuddyCommTk.h>
|
||||
|
||||
bool UpdateFileAttribsMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
const char* logContext = "UpdateFileAttribsMsg incoming";
|
||||
|
||||
MetaStore* metaStore = Program::getApp()->getMetaStore();
|
||||
EntryLockStore* entryLockStore = Program::getApp()->getMirroredSessions()->getEntryLockStore();
|
||||
|
||||
FsckFileInodeList& inodes = getInodes();
|
||||
FsckFileInodeList failedInodes;
|
||||
|
||||
for (FsckFileInodeListIter iter = inodes.begin(); iter != inodes.end(); iter++)
|
||||
{
|
||||
// create an EntryInfo object (NOTE: dummy fileName)
|
||||
EntryInfo entryInfo(iter->getSaveNodeID(), iter->getParentDirID(), iter->getID(), "",
|
||||
DirEntryType_REGULARFILE,
|
||||
(iter->getIsBuddyMirrored() ? ENTRYINFO_FEATURE_BUDDYMIRRORED : 0) |
|
||||
(iter->getIsInlined() ? ENTRYINFO_FEATURE_INLINED : 0));
|
||||
|
||||
FileIDLock lock;
|
||||
|
||||
if (iter->getIsBuddyMirrored())
|
||||
lock = {entryLockStore, entryInfo.getEntryID(), true};
|
||||
|
||||
auto [inode, referenceRes] = metaStore->referenceFile(&entryInfo);
|
||||
|
||||
if (inode)
|
||||
{
|
||||
inode->setNumHardlinksUnpersistent(iter->getNumHardLinks());
|
||||
inode->updateInodeOnDisk(&entryInfo);
|
||||
|
||||
// call the dynamic attribs refresh method
|
||||
FhgfsOpsErr refreshRes = MsgHelperStat::refreshDynAttribs(&entryInfo, true,
|
||||
getMsgHeaderUserID() );
|
||||
if (refreshRes != FhgfsOpsErr_SUCCESS)
|
||||
{
|
||||
LogContext(logContext).log(Log_WARNING, "Failed to update dynamic attributes of file. "
|
||||
"entryID: " + iter->getID());
|
||||
failedInodes.push_back(*iter);
|
||||
}
|
||||
|
||||
/* only release it here, as refreshDynAttribs() also takes an inode reference and can
|
||||
* do the reference from in-memory data then */
|
||||
metaStore->releaseFile(entryInfo.getParentEntryID(), inode);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogContext(logContext).log(Log_WARNING, "Could not reference inode to update attributes. "
|
||||
"entryID: " + iter->getID());
|
||||
failedInodes.push_back(*iter);
|
||||
}
|
||||
}
|
||||
|
||||
ctx.sendResponse(UpdateFileAttribsRespMsg(&failedInodes) );
|
||||
|
||||
return true;
|
||||
}
|
||||
12
meta/source/net/message/fsck/UpdateFileAttribsMsgEx.h
Normal file
12
meta/source/net/message/fsck/UpdateFileAttribsMsgEx.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/NetMessage.h>
|
||||
#include <common/net/message/fsck/UpdateFileAttribsMsg.h>
|
||||
#include <common/net/message/fsck/UpdateFileAttribsRespMsg.h>
|
||||
|
||||
class UpdateFileAttribsMsgEx : public UpdateFileAttribsMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user