#pragma once #include #include #include #include #include #include #include #include class DirInode; typedef AtomicObjectReferencer DirectoryReferencer; typedef std::map DirectoryMap; typedef DirectoryMap::iterator DirectoryMapIter; typedef DirectoryMap::const_iterator DirectoryMapCIter; typedef DirectoryMap::value_type DirectoryMapVal; typedef std::map DirCacheMap; // keys are dirIDs (same as DirMap) typedef DirCacheMap::iterator DirCacheMapIter; typedef DirCacheMap::const_iterator DirCacheMapCIter; typedef DirCacheMap::value_type DirCacheMapVal; typedef DirCacheMap::size_type DirCacheMapSizeT; /** * Layer in between our inodes and the data on the underlying file system. So we read/write from/to * underlying files and this class is to do this corresponding data access. * This object is used for for _directories_ only. */ class InodeDirStore { friend class DirInode; friend class MetaStore; public: InodeDirStore(); ~InodeDirStore() { this->clearStoreUnlocked(); }; InodeDirStore(const InodeDirStore&) = delete; InodeDirStore(InodeDirStore&&) = delete; InodeDirStore& operator=(const InodeDirStore&) = delete; InodeDirStore& operator=(InodeDirStore&&) = delete; bool dirInodeInStoreUnlocked(const std::string& dirID); DirInode* referenceDirInode(const std::string& dirID, bool isBuddyMirrored, bool forceLoad); void releaseDir(const std::string& dirID); FhgfsOpsErr removeDirInode(const std::string& dirID, bool isBuddyMirrored); size_t getSize(); size_t getCacheSize(); FhgfsOpsErr stat(const std::string& dirID, bool isBuddyMirrored, StatData& outStatData, NumNodeID* outParentNodeID, std::string* outParentEntryID); FhgfsOpsErr setAttr(const std::string& dirID, bool isBuddyMirrored, int validAttribs, SettableFileAttribs* attribs); void invalidateMirroredDirInodes(); bool cacheSweepAsync(); private: DirectoryMap dirs; size_t refCacheSyncLimit; // synchronous access limit (=> async limit plus some grace size) size_t refCacheAsyncLimit; // asynchronous cleanup limit (this is what the user configures) Random randGen; // for random cache removal DirCacheMap refCache; RWLock rwlock; void releaseDirUnlocked(const std::string& dirID); FhgfsOpsErr isRemovableUnlocked(const std::string& dirID, bool isBuddyMirrored); DirectoryMapIter insertDirInodeUnlocked(const std::string& dirID, bool isBuddyMirrored, bool forceLoad); FhgfsOpsErr setDirParent(EntryInfo* entryInfo, uint16_t parentNodeID); void clearStoreUnlocked(); void cacheAddUnlocked(const std::string& dirID, DirectoryReferencer* dirRefer); void cacheRemoveUnlocked(const std::string& dirID); void cacheRemoveAllUnlocked(); bool cacheSweepUnlocked(bool isSyncSweep); };