116 lines
3.9 KiB
C++
116 lines
3.9 KiB
C++
#pragma once
|
|
|
|
#include <common/toolkit/ObjectReferencer.h>
|
|
#include <common/Common.h>
|
|
#include <common/threading/Mutex.h>
|
|
#include <common/toolkit/MetadataTk.h>
|
|
#include <common/storage/StorageDefinitions.h>
|
|
#include <common/storage/StorageErrors.h>
|
|
#include <storage/GlobalInodeLockStore.h>
|
|
#include "FileInode.h"
|
|
|
|
|
|
typedef ObjectReferencer<FileInode*> FileInodeReferencer;
|
|
typedef std::map<std::string, FileInodeReferencer*> InodeMap;
|
|
typedef InodeMap::iterator InodeMapIter;
|
|
typedef InodeMap::const_iterator InodeMapCIter;
|
|
typedef InodeMap::value_type InodeMapVal;
|
|
typedef std::pair<FileInode*, FhgfsOpsErr> FileInodeRes;
|
|
|
|
/**
|
|
* Layer in between our inodes and the data on the underlying file system. So we read/write from/to
|
|
* underlying inodes and this class is to do this corresponding data access.
|
|
* This object is used for all file types, for example regular files, but NOT directories.
|
|
*/
|
|
class InodeFileStore
|
|
{
|
|
friend class DirInode;
|
|
friend class MetaStore;
|
|
|
|
public:
|
|
InodeFileStore() {}
|
|
~InodeFileStore()
|
|
{
|
|
this->clearStoreUnlocked();
|
|
}
|
|
|
|
bool isInStore(const std::string& fileID);
|
|
FileInodeRes referenceFileInode(EntryInfo* entryInfo, bool loadFromDisk, bool checkLockStore);
|
|
FileInode* referenceLoadedFile(const std::string& entryID);
|
|
bool releaseFileInode(FileInode* inode);
|
|
FhgfsOpsErr unlinkFileInode(EntryInfo* entryInfo, std::unique_ptr<FileInode>* outInode);
|
|
void unlinkAllFiles();
|
|
|
|
FhgfsOpsErr moveRemoteBegin(EntryInfo* entryInfo, char* buf, size_t bufLen,
|
|
size_t* outUsedBufLen);
|
|
void moveRemoteComplete(const std::string& entryID);
|
|
|
|
size_t getSize();
|
|
|
|
bool closeFile(EntryInfo* entryInfo, FileInode* inode, unsigned accessFlags,
|
|
unsigned* outNumHardlinks, unsigned* outNumRefs, bool& outLastWriterClosed);
|
|
FhgfsOpsErr openFile(EntryInfo* entryInfo, unsigned accessFlags,
|
|
FileInode*& outInode, bool loadFromDisk, bool bypassAccessCheck);
|
|
|
|
FhgfsOpsErr stat(EntryInfo* entryInfo, bool loadFromDisk, StatData& outStatData);
|
|
FhgfsOpsErr setAttr(EntryInfo* entryInfo, int validAttribs, SettableFileAttribs* attribs);
|
|
|
|
FhgfsOpsErr isUnlinkable(EntryInfo* entryInfo);
|
|
|
|
private:
|
|
InodeMap inodes;
|
|
|
|
RWLock rwlock;
|
|
|
|
unsigned decreaseInodeRefCountUnlocked(InodeMapIter& iter);
|
|
FileInodeRes referenceFileInodeUnlocked(EntryInfo* entryInfo, bool loadFromDisk);
|
|
FileInodeRes referenceFileInodeUnlockedIgnoreLocking(EntryInfo* entryInfo, bool loadFromDisk);
|
|
FhgfsOpsErr getUnreferencedInodeUnlocked(EntryInfo* entryInfo, FileInode*& outInode);
|
|
void deleteUnreferencedInodeUnlocked(const std::string& entryID);
|
|
|
|
FhgfsOpsErr isUnlinkableUnlocked(EntryInfo* entryInfo);
|
|
|
|
FhgfsOpsErr unlinkFileInodeUnlocked(EntryInfo* entryInfo,
|
|
std::unique_ptr<FileInode>* outInode);
|
|
|
|
bool loadAndInsertFileInodeUnlocked(EntryInfo* entryInfo, InodeMapIter& newElemIter);
|
|
bool insertReferencer(std::string entryID, FileInodeReferencer* fileRefer);
|
|
|
|
FileInodeReferencer* getReferencerAndDeleteFromMap(const std::string& fileID);
|
|
|
|
void clearStoreUnlocked();
|
|
|
|
FileInode* referenceFileInodeMapIterUnlocked(InodeMapIter& iter);
|
|
|
|
FhgfsOpsErr incDecLinkCount(FileInode& inode, EntryInfo* entryInfo, int value);
|
|
|
|
public:
|
|
|
|
// inliners
|
|
|
|
FhgfsOpsErr incLinkCount(FileInode& inode, EntryInfo* entryInfo)
|
|
{
|
|
return incDecLinkCount(inode, entryInfo, 1);
|
|
}
|
|
|
|
FhgfsOpsErr decLinkCount(FileInode& inode, EntryInfo* entryInfo)
|
|
{
|
|
return incDecLinkCount(inode, entryInfo, -1);
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
// inliners
|
|
|
|
/**
|
|
* Create an unreferenced file inode from an existing inode on disk disk.
|
|
*/
|
|
FileInode* createUnreferencedInodeUnlocked(EntryInfo* entryInfo)
|
|
{
|
|
return FileInode::createFromEntryInfo(entryInfo);
|
|
}
|
|
|
|
};
|
|
|