Use std::shared_ptr to refer to FdEntity (#2541)

FdEntity may have multiple references due to ChangeEntityToTempPath.
This relies on the std::enable_shared_from_this helper to create a
std::shared_ptr from this.  Fixes #2532.
This commit is contained in:
Andrew Gaul
2024-10-20 14:56:29 +09:00
committed by GitHub
parent a505cebf9b
commit 4b6e53223b
4 changed files with 13 additions and 12 deletions

View File

@ -587,7 +587,7 @@ FdEntity* FdManager::Open(int& fd, const char* path, const headers_t* pmeta, off
return nullptr;
}
// make new obj
std::unique_ptr<FdEntity> ent(new FdEntity(path, cache_path.c_str()));
auto ent = std::make_shared<FdEntity>(path, cache_path.c_str());
// open
if(0 > (fd = ent->Open(pmeta, size, ts_mctime, flags))){
@ -696,7 +696,7 @@ void FdManager::Rename(const std::string &from, const std::string &to)
// found
S3FS_PRN_DBG("[from=%s][to=%s]", from.c_str(), to.c_str());
std::unique_ptr<FdEntity> ent(std::move(iter->second));
auto ent(std::move(iter->second));
// retrieve old fd entity from map
fent.erase(iter);
@ -746,10 +746,10 @@ bool FdManager::Close(FdEntity* ent, int fd)
return false;
}
bool FdManager::ChangeEntityToTempPath(FdEntity* ent, const char* path)
bool FdManager::ChangeEntityToTempPath(std::shared_ptr<FdEntity> ent, const char* path)
{
const std::lock_guard<std::mutex> lock(FdManager::except_entmap_lock);
except_fent[path] = ent;
except_fent[path] = std::move(ent);
return true;
}
@ -762,7 +762,7 @@ bool FdManager::UpdateEntityToTempPath()
FdManager::MakeRandomTempPath(except_iter->first.c_str(), tmppath);
auto iter = fent.find(except_iter->first);
if(fent.cend() != iter && iter->second.get() == except_iter->second){
if(fent.cend() != iter && iter->second.get() == except_iter->second.get()){
// Move the entry to the new key
fent[tmppath] = std::move(iter->second);
fent.erase(iter);
@ -778,7 +778,7 @@ bool FdManager::UpdateEntityToTempPath()
S3FS_PRN_WARN("For some reason the FdEntity pointer(for %s) is not found in the fent map. Recovery procedures are being performed, but the cause needs to be identified.", except_iter->first.c_str());
// Add the entry for recovery procedures
fent[tmppath] = std::unique_ptr<FdEntity>(except_iter->second);
fent[tmppath] = except_iter->second;
except_iter = except_fent.erase(except_iter);
}
}

View File

@ -48,7 +48,7 @@ class FdManager
static std::string tmp_dir;
fdent_map_t fent GUARDED_BY(fd_manager_lock);
fdent_direct_map_t except_fent GUARDED_BY(except_entmap_lock); // A map of delayed deletion fdentity
fdent_map_t except_fent GUARDED_BY(except_entmap_lock); // A map of delayed deletion fdentity
private:
static off_t GetFreeDiskSpaceHasLock(const char* path) REQUIRES(FdManager::reserved_diskspace_lock);
@ -115,7 +115,7 @@ class FdManager
FdEntity* OpenExistFdEntity(const char* path, int& fd, int flags = O_RDONLY);
void Rename(const std::string &from, const std::string &to);
bool Close(FdEntity* ent, int fd);
bool ChangeEntityToTempPath(FdEntity* ent, const char* path);
bool ChangeEntityToTempPath(std::shared_ptr<FdEntity> ent, const char* path);
void CleanupCacheDir();
bool CheckAllCache();

View File

@ -1086,7 +1086,7 @@ int FdEntity::NoCacheLoadAndPost(PseudoFdInfo* pseudo_obj, off_t start, off_t si
}
// Change entity key in manager mapping
FdManager::get()->ChangeEntityToTempPath(this, path.c_str());
FdManager::get()->ChangeEntityToTempPath(get_shared_ptr(), path.c_str());
// open temporary file
int tmpfd;

View File

@ -41,7 +41,7 @@ typedef std::map<int, std::unique_ptr<PseudoFdInfo>> fdinfo_map_t;
//------------------------------------------------
// class FdEntity
//------------------------------------------------
class FdEntity
class FdEntity : public std::enable_shared_from_this<FdEntity>
{
private:
// [NOTE]
@ -109,6 +109,8 @@ class FdEntity
bool IsDirtyMetadata() const REQUIRES(FdEntity::fdent_data_lock);
std::shared_ptr<FdEntity> get_shared_ptr() { return shared_from_this(); }
public:
static bool GetNoMixMultipart() { return mixmultipart; }
static bool SetNoMixMultipart();
@ -235,8 +237,7 @@ class FdEntity
std::mutex* GetMutex() RETURN_CAPABILITY(fdent_lock);
};
typedef std::map<std::string, std::unique_ptr<FdEntity>> fdent_map_t; // key=path, value=unique_ptr<FdEntity>
typedef std::map<std::string, FdEntity*> fdent_direct_map_t; // key=path, value=FdEntity*
typedef std::map<std::string, std::shared_ptr<FdEntity>> fdent_map_t; // key=path, value=FdEntity
#endif // S3FS_FDCACHE_ENTITY_H_