Changed to use rename when serializing to FileCacheStat

This commit is contained in:
Takeshi Nakatani
2025-08-28 14:22:17 +00:00
committed by Andrew Gaul
parent da17cace4f
commit 28771e5757
5 changed files with 52 additions and 18 deletions

View File

@ -820,32 +820,21 @@ bool PageList::ClearAllModified()
return Compress(); return Compress();
} }
bool PageList::Serialize(CacheFileStat& file, ino_t inode) bool PageList::Serialize(const CacheFileStat& file, ino_t inode) const
{ {
if(!file.Open()){ // make contents
return false;
}
//
// put to file
//
std::ostringstream ssall; std::ostringstream ssall;
ssall << inode << ":" << Size(); ssall << inode << ":" << Size();
for(auto iter = pages.cbegin(); iter != pages.cend(); ++iter){ for(auto iter = pages.cbegin(); iter != pages.cend(); ++iter){
ssall << "\n" << iter->offset << ":" << iter->bytes << ":" << (iter->loaded ? "1" : "0") << ":" << (iter->modified ? "1" : "0"); ssall << "\n" << iter->offset << ":" << iter->bytes << ":" << (iter->loaded ? "1" : "0") << ":" << (iter->modified ? "1" : "0");
} }
if(-1 == ftruncate(file.GetFd(), 0)){
S3FS_PRN_ERR("failed to truncate file(to 0) for stats(%d)", errno);
return false;
}
std::string strall = ssall.str(); std::string strall = ssall.str();
if(0 >= pwrite(file.GetFd(), strall.c_str(), strall.length(), 0)){
S3FS_PRN_ERR("failed to write stats(%d)", errno); // over write
if(!file.OverWriteFile(strall)){
return false; return false;
} }
return true; return true;
} }

View File

@ -94,7 +94,7 @@ class PageList
void Clear(); void Clear();
bool Parse(off_t new_pos); bool Parse(off_t new_pos);
bool Serialize(CacheFileStat& file, ino_t inode); bool Serialize(const CacheFileStat& file, ino_t inode) const;
public: public:
static void FreeList(fdpage_list_t& list); static void FreeList(fdpage_list_t& list);

View File

@ -193,6 +193,49 @@ bool CacheFileStat::SetPath(const char* tpath, bool is_open)
return Open(); return Open();
} }
// [NOTE]
// There is no need to check whether the file is open because using rename().
//
bool CacheFileStat::OverWriteFile(const std::string& strall) const
{
// make temporary file path(in same cache directory)
std::string sfile_path;
if(0 != CacheFileStat::MakeCacheFileStatPath(path.c_str(), sfile_path, true)){
S3FS_PRN_ERR("failed to create cache stat file path(%s)", path.c_str());
return false;
}
std::string strTmpFile = mydirname(sfile_path) + "/.tmpstat.XXXXXX";
strTmpFile.push_back('\0'); // terminate with a null character and allocate space for it.
// open temporary file(mode: 0600)
//
// [TODO]
// Currently, use "&str[pos]" to make it possible to build with C++14.
// Once we support C++17 or later, we will use "str.data()".
//
int tmpfd;
if(-1 == (tmpfd = mkstemp(&strTmpFile[0]))){ // NOLINT(readability-container-data-pointer)
S3FS_PRN_ERR("failed to create temporary cache stat file path(%s) for %s cache", strTmpFile.c_str(), sfile_path.c_str());
return false;
}
// write contents
if(0 >= pwrite(tmpfd, strall.c_str(), strall.length(), 0)){
S3FS_PRN_ERR("failed to write stats to temporary file(%d)", errno);
close(tmpfd);
return false;
}
close(tmpfd);
// rename
if(0 != rename(strTmpFile.c_str(), sfile_path.c_str())){
S3FS_PRN_ERR("failed to rename temporary cache stat file path(%s) to %s cache", strTmpFile.c_str(), sfile_path.c_str());
unlink(strTmpFile.c_str());
return false;
}
return true;
}
bool CacheFileStat::RawOpen(bool readonly) bool CacheFileStat::RawOpen(bool readonly)
{ {
if(path.empty()){ if(path.empty()){

View File

@ -56,6 +56,7 @@ class CacheFileStat
bool Release(); bool Release();
bool SetPath(const char* tpath, bool is_open = true); bool SetPath(const char* tpath, bool is_open = true);
int GetFd() const { return fd; } int GetFd() const { return fd; }
bool OverWriteFile(const std::string& strall) const;
}; };
#endif // S3FS_FDCACHE_STAT_H_ #endif // S3FS_FDCACHE_STAT_H_

View File

@ -22,7 +22,8 @@
#include "fdcache_stat.h" #include "fdcache_stat.h"
#include "test_util.h" #include "test_util.h"
bool CacheFileStat::Open() { return false; } // NOLINT(readability-convert-member-functions-to-static) bool CacheFileStat::Open() { return false; } // NOLINT(readability-convert-member-functions-to-static)
bool CacheFileStat::OverWriteFile(const std::string& strall) const { return false; } // NOLINT(readability-convert-member-functions-to-static)
void test_compress() void test_compress()
{ {