Added a flag to prevent stats cache expiration checks
This commit is contained in:
committed by
Andrew Gaul
parent
52b263b99c
commit
b2e318c5c7
@ -99,6 +99,8 @@ bool StatCacheNode::IsExpireIntervalType = false;
|
|||||||
time_t StatCacheNode::ExpireTime = 15 * 60;
|
time_t StatCacheNode::ExpireTime = 15 * 60;
|
||||||
bool StatCacheNode::UseNegativeCache = true;
|
bool StatCacheNode::UseNegativeCache = true;
|
||||||
std::mutex StatCacheNode::cache_lock;
|
std::mutex StatCacheNode::cache_lock;
|
||||||
|
unsigned long StatCacheNode::DisableCheckingExpire = 0L;
|
||||||
|
struct timespec StatCacheNode::DisableExpireDate = {0, 0};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Class Methods
|
// Class Methods
|
||||||
@ -162,6 +164,57 @@ bool StatCacheNode::SetNegativeCache(bool flag)
|
|||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StatCacheNode::NeedExpireCheckHasLock(const struct timespec& ts)
|
||||||
|
{
|
||||||
|
if(!StatCacheNode::IsEnableExpireTime()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [NOTE]
|
||||||
|
// If the expiration date check is disabled(0 < DisableCheckingExpire)
|
||||||
|
// and the date is later than DisableExpireDate, it is determined that
|
||||||
|
// checking is not necessary.
|
||||||
|
//
|
||||||
|
if(0L < StatCacheNode::DisableCheckingExpire){
|
||||||
|
if(0 >= CompareStatCacheTime(StatCacheNode::DisableExpireDate, ts)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StatCacheNode::PreventExpireCheck()
|
||||||
|
{
|
||||||
|
if(!StatCacheNode::IsEnableExpireTime()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::lock_guard<std::mutex> lock(StatCacheNode::cache_lock);
|
||||||
|
|
||||||
|
++StatCacheNode::DisableCheckingExpire;
|
||||||
|
|
||||||
|
if(0 == StatCacheNode::DisableExpireDate.tv_sec){
|
||||||
|
SetCurrentTime(StatCacheNode::DisableExpireDate);
|
||||||
|
StatCacheNode::DisableExpireDate.tv_sec -= StatCacheNode::GetExpireTime();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StatCacheNode::ResumeExpireCheck()
|
||||||
|
{
|
||||||
|
if(!StatCacheNode::IsEnableExpireTime()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::lock_guard<std::mutex> lock(StatCacheNode::cache_lock);
|
||||||
|
|
||||||
|
if(0 < StatCacheNode::DisableCheckingExpire){
|
||||||
|
--StatCacheNode::DisableCheckingExpire;
|
||||||
|
}
|
||||||
|
if(0 == StatCacheNode::DisableCheckingExpire){
|
||||||
|
StatCacheNode::DisableExpireDate = {0, 0};
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Methods
|
// Methods
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
@ -654,7 +707,7 @@ s3obj_type_map_t::size_type StatCacheNode::GetChildMap(s3obj_type_map_t& childma
|
|||||||
|
|
||||||
bool StatCacheNode::IsExpireStatCacheTimeHasLock() const
|
bool StatCacheNode::IsExpireStatCacheTimeHasLock() const
|
||||||
{
|
{
|
||||||
if(StatCacheNode::IsEnableExpireTime()){
|
if(NeedExpireCheckHasLock(cache_date)){
|
||||||
if(IsExpireStatCacheTime(cache_date, StatCacheNode::GetExpireTime())){
|
if(IsExpireStatCacheTime(cache_date, StatCacheNode::GetExpireTime())){
|
||||||
// this cache is expired
|
// this cache is expired
|
||||||
return true;
|
return true;
|
||||||
@ -1182,11 +1235,12 @@ std::shared_ptr<StatCacheNode> DirStatCache::FindHasLock(const std::string& strp
|
|||||||
|
|
||||||
bool DirStatCache::NeedTruncateProcessing()
|
bool DirStatCache::NeedTruncateProcessing()
|
||||||
{
|
{
|
||||||
if(!StatCacheNode::IsEnableExpireTime()){
|
std::lock_guard<std::mutex> lock(StatCacheNode::cache_lock);
|
||||||
|
if(!NeedExpireCheckHasLock(cache_date)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::lock_guard<std::mutex> dircachelock(dir_cache_lock);
|
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> dircachelock(dir_cache_lock);
|
||||||
return IsExpireStatCacheTime(last_check_date, StatCacheNode::GetExpireTime());
|
return IsExpireStatCacheTime(last_check_date, StatCacheNode::GetExpireTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -79,6 +79,8 @@ class StatCacheNode : public std::enable_shared_from_this<StatCacheNode>
|
|||||||
static time_t ExpireTime;
|
static time_t ExpireTime;
|
||||||
static bool UseNegativeCache;
|
static bool UseNegativeCache;
|
||||||
static std::mutex cache_lock; // for internal data
|
static std::mutex cache_lock; // for internal data
|
||||||
|
static unsigned long DisableCheckingExpire GUARDED_BY(cache_lock); // If greater than 0, it disables the expiration check, which allows disabling checks during processing.
|
||||||
|
static struct timespec DisableExpireDate GUARDED_BY(cache_lock); // Data registerd after this time will not be truncated(if 0 < DisableCheckingExpire)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
objtype_t cache_type GUARDED_BY(StatCacheNode::cache_lock) = objtype_t::UNKNOWN; // object type is set in the constructor(except dir).
|
objtype_t cache_type GUARDED_BY(StatCacheNode::cache_lock) = objtype_t::UNKNOWN; // object type is set in the constructor(except dir).
|
||||||
@ -97,6 +99,7 @@ class StatCacheNode : public std::enable_shared_from_this<StatCacheNode>
|
|||||||
static void IncrementCacheCount(objtype_t type);
|
static void IncrementCacheCount(objtype_t type);
|
||||||
static void DecrementCacheCount(objtype_t type);
|
static void DecrementCacheCount(objtype_t type);
|
||||||
static bool SetNegativeCache(bool flag);
|
static bool SetNegativeCache(bool flag);
|
||||||
|
static bool NeedExpireCheckHasLock(const struct timespec& ts) REQUIRES(StatCacheNode::cache_lock);
|
||||||
|
|
||||||
// Cache Type
|
// Cache Type
|
||||||
bool isSameObjectTypeHasLock(objtype_t type) const REQUIRES(StatCacheNode::cache_lock);
|
bool isSameObjectTypeHasLock(objtype_t type) const REQUIRES(StatCacheNode::cache_lock);
|
||||||
@ -156,6 +159,8 @@ class StatCacheNode : public std::enable_shared_from_this<StatCacheNode>
|
|||||||
static bool EnableNegativeCache() { return SetNegativeCache(true); }
|
static bool EnableNegativeCache() { return SetNegativeCache(true); }
|
||||||
static bool DisableNegativeCache() { return SetNegativeCache(false); }
|
static bool DisableNegativeCache() { return SetNegativeCache(false); }
|
||||||
static bool IsEnabledNegativeCache() { return UseNegativeCache; }
|
static bool IsEnabledNegativeCache() { return UseNegativeCache; }
|
||||||
|
static bool PreventExpireCheck();
|
||||||
|
static bool ResumeExpireCheck();
|
||||||
|
|
||||||
// Constructor/Destructor
|
// Constructor/Destructor
|
||||||
explicit StatCacheNode(const char* path = nullptr, objtype_t type = objtype_t::UNKNOWN);
|
explicit StatCacheNode(const char* path = nullptr, objtype_t type = objtype_t::UNKNOWN);
|
||||||
@ -321,6 +326,28 @@ class NegativeStatCache : public StatCacheNode
|
|||||||
NegativeStatCache& operator=(NegativeStatCache&&) = delete;
|
NegativeStatCache& operator=(NegativeStatCache&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Class : PreventStatCacheExpire
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
class PreventStatCacheExpire
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit PreventStatCacheExpire()
|
||||||
|
{
|
||||||
|
StatCacheNode::PreventExpireCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
~PreventStatCacheExpire()
|
||||||
|
{
|
||||||
|
StatCacheNode::ResumeExpireCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
PreventStatCacheExpire(const PreventStatCacheExpire&) = delete;
|
||||||
|
PreventStatCacheExpire(PreventStatCacheExpire&&) = delete;
|
||||||
|
PreventStatCacheExpire& operator=(const PreventStatCacheExpire&) = delete;
|
||||||
|
PreventStatCacheExpire& operator=(PreventStatCacheExpire&&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // S3FS_CACHE_NODE_H_
|
#endif // S3FS_CACHE_NODE_H_
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -1231,6 +1231,9 @@ static int s3fs_mkdir(const char* _path, mode_t mode)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keep stat cache without checking expiration
|
||||||
|
PreventStatCacheExpire nocacheexpire;
|
||||||
|
|
||||||
// check parent directory attribute.
|
// check parent directory attribute.
|
||||||
if(0 != (result = check_parent_object_access(path, W_OK | X_OK))){
|
if(0 != (result = check_parent_object_access(path, W_OK | X_OK))){
|
||||||
return result;
|
return result;
|
||||||
@ -1322,6 +1325,9 @@ static int s3fs_rmdir(const char* _path)
|
|||||||
|
|
||||||
FUSE_CTX_INFO("[path=%s]", path);
|
FUSE_CTX_INFO("[path=%s]", path);
|
||||||
|
|
||||||
|
// keep stat cache without checking expiration
|
||||||
|
PreventStatCacheExpire nocacheexpire;
|
||||||
|
|
||||||
if(0 != (result = check_parent_object_access(path, W_OK | X_OK))){
|
if(0 != (result = check_parent_object_access(path, W_OK | X_OK))){
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user