beegfs/meta/source/storage/MetaStore.h
2025-08-10 01:34:16 +02:00

203 lines
9.8 KiB
C++

#pragma once
#include <common/fsck/FsckDirInode.h>
#include <common/storage/striping/StripePattern.h>
#include <common/storage/RemoteStorageTarget.h>
#include <common/storage/Metadata.h>
#include <common/storage/StorageDefinitions.h>
#include <common/storage/StorageErrors.h>
#include <common/storage/EntryInfo.h>
#include <common/threading/SafeRWLock.h>
#include <common/threading/Atomics.h>
#include <common/toolkit/FsckTk.h>
#include <common/Common.h>
#include <storage/GlobalInodeLockStore.h>
#include <storage/IncompleteInode.h>
#include <storage/MkFileDetails.h>
#include <session/EntryLock.h>
#include "DirEntry.h"
#include "InodeDirStore.h"
#include "InodeFileStore.h"
#include "MetadataEx.h"
#include "MetaFileHandle.h"
typedef std::pair<MetaFileHandle, FhgfsOpsErr> MetaFileHandleRes;
/*
* This is the main class for all client side posix io operations regarding the meta server.
* So client side net message will do io via this class.
*/
class MetaStore
{
public:
DirInode* referenceDir(const std::string& dirID, const bool isBuddyMirrored,
const bool forceLoad);
void releaseDir(const std::string& dirID);
MetaFileHandleRes referenceFile(EntryInfo* entryInfo, bool checkLockStore = true);
MetaFileHandle referenceLoadedFile(const std::string& parentEntryID,
bool parentIsBuddyMirrored, const std::string& entryID);
bool releaseFile(const std::string& parentEntryID, MetaFileHandle& inode);
bool referenceInode(const std::string& entryID, bool isBuddyMirrored,
MetaFileHandle& outFileInode, DirInode*& outDirInode);
FhgfsOpsErr openFile(EntryInfo* entryInfo, unsigned accessFlags, bool bypassAccessCheck,
MetaFileHandle& outInode, bool checkDisposalFirst = false);
void closeFile(EntryInfo* entryInfo, MetaFileHandle inode, unsigned accessFlags,
unsigned* outNumHardlinks, unsigned* outNumRefs, bool& outLastWriterClosed);
FhgfsOpsErr stat(EntryInfo* entryInfo, bool loadFromDisk, StatData& outStatData,
NumNodeID* outParentNodeID = NULL, std::string* outParentEntryID = NULL);
FhgfsOpsErr setAttr(EntryInfo* entryInfo, int validAttribs, SettableFileAttribs* attribs);
FhgfsOpsErr incDecLinkCount(EntryInfo* entryInfo, int value);
FhgfsOpsErr setDirParent(EntryInfo* entryInfo, NumNodeID parentNodeID);
FhgfsOpsErr mkNewMetaFile(DirInode& dir, MkFileDetails* mkDetails,
std::unique_ptr<StripePattern> stripePattern, RemoteStorageTarget* rstInfo,
EntryInfo* outEntryInfo, FileInodeStoreData* outInodeData);
FhgfsOpsErr makeDirInode(DirInode& inode);
FhgfsOpsErr makeDirInode(DirInode& inode, const CharVector& defaultACLXAttr,
const CharVector& accessACLXAttr);
FhgfsOpsErr removeDirInode(const std::string& entryID, bool isBuddyMirrored);
FhgfsOpsErr unlinkInode(EntryInfo* entryInfo, std::unique_ptr<FileInode>* outInode);
FhgfsOpsErr fsckUnlinkFileInode(const std::string& entryID, bool isBuddyMirrored);
FhgfsOpsErr unlinkFile(DirInode& dir, const std::string& fileName,
EntryInfo* outEntryInfo, std::unique_ptr<FileInode>* outInode, unsigned& outNumHardlinks);
FhgfsOpsErr unlinkFileInode(EntryInfo* delFileInfo, std::unique_ptr<FileInode>* outInode,
unsigned& outNumHardlinks);
FhgfsOpsErr unlinkInodeLater(EntryInfo* entryInfo, bool wasInlined);
FhgfsOpsErr renameInSameDir(DirInode& parentDir, const std::string& fromName,
const std::string& toName, std::unique_ptr<FileInode>* outUnlinkInode,
DirEntry*& outOverWrittenEntry, bool& outUnlinkedWasInlined);
FhgfsOpsErr moveRemoteFileInsert(EntryInfo* fromFileInfo, DirInode& toParent,
const std::string& newEntryName, const char* buf, uint32_t bufLen,
std::unique_ptr<FileInode>* outUnlinkedInode, EntryInfo* overWriteInfo, EntryInfo& newFileInfo);
FhgfsOpsErr moveRemoteFileBegin(DirInode& dir, EntryInfo* entryInfo, char* buf, size_t bufLen,
size_t* outUsedBufLen);
void moveRemoteFileComplete(DirInode& dir, const std::string& entryID);
FhgfsOpsErr getAllInodesIncremental(unsigned hashDirNum, int64_t lastOffset,
unsigned maxOutInodes, FsckDirInodeList* outDirInodes, FsckFileInodeList* outFileInodes,
int64_t* outNewOffset, bool isBuddyMirrored);
FhgfsOpsErr getAllEntryIDFilesIncremental(unsigned firstLevelhashDirNum,
unsigned secondLevelhashDirNum, int64_t lastOffset, unsigned maxOutEntries,
StringList* outEntryIDFiles, int64_t* outNewOffset, bool buddyMirrored);
void getReferenceStats(size_t* numReferencedDirs, size_t* numReferencedFiles);
void getCacheStats(size_t* numCachedDirs);
bool cacheSweepAsync();
FhgfsOpsErr insertDisposableFile(FileInode* inode);
std::pair<FhgfsOpsErr, bool> getEntryData(DirInode *dirInode, const std::string& entryName,
EntryInfo* outInfo, FileInodeStoreData* outInodeMetaData);
FhgfsOpsErr getEntryData(EntryInfo* inEntryInfo, FileInodeStoreData* outInodeMetaData);
FhgfsOpsErr linkInSameDir(DirInode& parentDir, EntryInfo* fromFileInfo,
const std::string& fromName, const std::string& toName);
std::pair<FhgfsOpsErr, unsigned> makeNewHardlink(EntryInfo* fromFileInfo);
FhgfsOpsErr verifyAndMoveFileInode(DirInode& parentDir, EntryInfo* fileInfo,
FileInodeMode moveMode);
FhgfsOpsErr checkAndRepairDupFileInode(DirInode& parentDir, EntryInfo* entryInfo);
FhgfsOpsErr getRawMetadata(const Path& path, const char* attrName, CharVector& contents);
std::pair<FhgfsOpsErr, IncompleteInode> beginResyncFor(const Path& path, bool isDirectory);
FhgfsOpsErr unlinkRawMetadata(const Path& path);
FhgfsOpsErr setFileState(EntryInfo* entryInfo, const FileState& state);
void invalidateMirroredDirInodes();
private:
InodeDirStore dirStore;
/* We need to avoid to use that one, as it is a global store, with possible lots of entries.
* So access to the map is slow and inserting entries blocks the entire MetaStore */
InodeFileStore fileStore;
GlobalInodeLockStore inodeLockStore;
RWLock rwlock; /* note: this is mostly not used as a read/write-lock but rather a shared/excl
lock (because we're not really modifying anyting directly) - especially relevant for the
mutliple dirStore locking dual-move methods */
FhgfsOpsErr isFileUnlinkable(DirInode& subDir, EntryInfo* entryInfo);
FhgfsOpsErr mkMetaFileUnlocked(DirInode& dir, const std::string& entryName,
EntryInfo* entryInfo, FileInode* inode);
FhgfsOpsErr unlinkInodeUnlocked(EntryInfo* entryInfo, DirInode* subDir,
std::unique_ptr<FileInode>* outInode);
FhgfsOpsErr unlinkInodeLaterUnlocked(EntryInfo* entryInfo, bool wasInlined);
FhgfsOpsErr unlinkFileUnlocked(DirInode& subdir, const std::string& fileName,
std::unique_ptr<FileInode>* outInode, EntryInfo* outEntryInfo, bool& outWasInlined,
unsigned& outNumHardlinks);
FhgfsOpsErr unlinkDirEntryWithInlinedInodeUnlocked(const std::string& entryName,
DirInode& subDir, DirEntry* dirEntry, unsigned unlinkTypeFlags,
std::unique_ptr<FileInode>* outInode, unsigned& outNumHardlinks);
FhgfsOpsErr unlinkDentryAndInodeUnlocked(const std::string& fileName, DirInode& subdir,
DirEntry* dirEntry, unsigned unlinkTypeFlags, std::unique_ptr<FileInode>* outInode,
unsigned& outNumHardlinks);
FhgfsOpsErr unlinkOverwrittenEntry(DirInode& parentDir, DirEntry* overWrittenEntry,
std::unique_ptr<FileInode>* outInode);
FhgfsOpsErr unlinkOverwrittenEntryUnlocked(DirInode& parentDir, DirEntry* overWrittenEntry,
std::unique_ptr<FileInode>* outInode);
DirInode* referenceDirUnlocked(const std::string& dirID, bool isBuddyMirrored,
bool forceLoad);
void releaseDirUnlocked(const std::string& dirID);
MetaFileHandleRes referenceFileUnlocked(EntryInfo* entryInfo, bool checkLockStore = true);
MetaFileHandleRes referenceFileUnlocked(DirInode& subDir, EntryInfo* entryInfo,
bool checkLockStore = true);
MetaFileHandle referenceLoadedFileUnlocked(const std::string& parentEntryID,
bool isBuddyMirrored, const std::string& entryID);
MetaFileHandle referenceLoadedFileUnlocked(DirInode& subDir, const std::string& entryID);
bool releaseFileUnlocked(const std::string& parentEntryID, MetaFileHandle& inode);
bool releaseFileUnlocked(DirInode& subDir, MetaFileHandle& inode);
MetaFileHandleRes tryReferenceFileWriteLocked(EntryInfo* entryInfo, bool checkLockStore = true);
FhgfsOpsErr tryOpenFileWriteLocked(EntryInfo* entryInfo, unsigned accessFlags, bool bypassAccessCheck,
MetaFileHandle& outInode);
bool moveReferenceToMetaFileStoreUnlocked(const std::string& parentEntryID,
bool parentIsBuddyMirrored, const std::string& entryID);
FhgfsOpsErr performRenameEntryInSameDir(DirInode& dir, const std::string& fromName,
const std::string& toName, DirEntry** outOverwrittenEntry);
FhgfsOpsErr checkRenameOverwrite(EntryInfo* fromEntry, EntryInfo* overWriteEntry,
bool& outIsSameInode);
FhgfsOpsErr setAttrUnlocked(EntryInfo* entryInfo, int validAttribs,
SettableFileAttribs* attribs);
FhgfsOpsErr incDecLinkCountUnlocked(EntryInfo* entryInfo, int value);
FhgfsOpsErr verifyAndMoveFileInodeUnlocked(DirInode& parentDir, EntryInfo* fileInfo,
FileInodeMode moveMode);
FhgfsOpsErr deinlineFileInode(DirInode& parentDir, EntryInfo* entryInfo,
DirEntry& dentry, const std::string& dirEntryPath);
FhgfsOpsErr reinlineFileInode(DirInode& parentDir, EntryInfo* entryInfo,
DirEntry& dentry, const std::string& dirEntryPath);
public:
// getters & setters
GlobalInodeLockStore* getInodeLockStore()
{
return &inodeLockStore;
}
// inliners
};