in src/cache.cpp [322:405]
bool StatCache::GetStat(const std::string& key, struct stat* pst, headers_t* meta, bool overcheck, const char* petag, bool* pisforce, bool *pisfake)
{
bool is_delete_cache = false;
std::string strpath = key;
AutoLock lock(&StatCache::stat_cache_lock);
stat_cache_t::iterator iter = stat_cache.end();
if(overcheck && '/' != *strpath.rbegin()){
strpath += "/";
iter = stat_cache.find(strpath);
}
if(iter == stat_cache.end()){
strpath = key;
iter = stat_cache.find(strpath);
}
if(iter != stat_cache.end() && (*iter).second){
stat_cache_entry* ent = (*iter).second;
if(0 < ent->notruncate || !IsExpireTime || !IsExpireStatCacheTime(ent->cache_date, ExpireTime)){
if(ent->noobjcache){
if(!IsCacheNoObject){
// need to delete this cache.
DelStat(strpath, /*lock_already_held=*/ true);
}else{
// noobjcache = true means no object.
}
return false;
}
// hit without checking etag
std::string stretag;
if(petag){
// find & check ETag
for(headers_t::iterator hiter = ent->meta.begin(); hiter != ent->meta.end(); ++hiter){
std::string tag = lower(hiter->first);
if(tag == "etag"){
stretag = hiter->second;
if('\0' != petag[0] && 0 != strcmp(petag, stretag.c_str())){
is_delete_cache = true;
}
break;
}
}
}
if(is_delete_cache){
// not hit by different ETag
S3FS_PRN_DBG("stat cache not hit by ETag[path=%s][time=%lld.%09ld][hit count=%lu][ETag(%s)!=(%s)]",
strpath.c_str(), static_cast<long long>(ent->cache_date.tv_sec), ent->cache_date.tv_nsec, ent->hit_count, petag ? petag : "null", stretag.c_str());
}else{
// hit
S3FS_PRN_DBG("stat cache hit [path=%s][time=%lld.%09ld][hit count=%lu]",
strpath.c_str(), static_cast<long long>(ent->cache_date.tv_sec), ent->cache_date.tv_nsec, ent->hit_count);
if(pst!= NULL){
*pst= ent->stbuf;
}
if(meta != NULL){
*meta = ent->meta;
}
if(pisforce != NULL){
(*pisforce) = ent->isforce;
}
if (pisfake != NULL) {
(*pisfake) = ent->isfake;
}
ent->hit_count++;
if(IsExpireIntervalType){
SetStatCacheTime(ent->cache_date);
}
return true;
}
}else{
// timeout
is_delete_cache = true;
}
}
if(is_delete_cache){
DelStat(strpath, /*lock_already_held=*/ true);
}
return false;
}