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();
}
bool PageList::Serialize(CacheFileStat& file, ino_t inode)
bool PageList::Serialize(const CacheFileStat& file, ino_t inode) const
{
if(!file.Open()){
return false;
}
//
// put to file
//
// make contents
std::ostringstream ssall;
ssall << inode << ":" << Size();
for(auto iter = pages.cbegin(); iter != pages.cend(); ++iter){
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();
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 true;
}

View File

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

View File

@ -193,6 +193,49 @@ bool CacheFileStat::SetPath(const char* tpath, bool is_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)
{
if(path.empty()){

View File

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

View File

@ -22,7 +22,8 @@
#include "fdcache_stat.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()
{