mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-11-13 07:56:30 +00:00
Merge pull request #371 from ggtakec/master
Always set stats cache for opened file
This commit is contained in:
commit
fbd8959d69
@ -328,9 +328,9 @@ bool StatCache::IsNoObjectCache(string& key, bool overcheck)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StatCache::AddStat(std::string& key, headers_t& meta, bool forcedir)
|
||||
bool StatCache::AddStat(std::string& key, headers_t& meta, bool forcedir, bool no_truncate)
|
||||
{
|
||||
if(CacheSize< 1){
|
||||
if(!no_truncate && CacheSize< 1){
|
||||
return true;
|
||||
}
|
||||
S3FS_PRN_INFO3("add stat cache entry[path=%s]", key.c_str());
|
||||
@ -361,6 +361,7 @@ bool StatCache::AddStat(std::string& key, headers_t& meta, bool forcedir)
|
||||
ent->hit_count = 0;
|
||||
ent->isforce = forcedir;
|
||||
ent->noobjcache = false;
|
||||
ent->notruncate = (no_truncate ? 1L : 0L);
|
||||
ent->meta.clear();
|
||||
SetStatCacheTime(ent->cache_date); // Set time.
|
||||
//copy only some keys
|
||||
@ -420,6 +421,7 @@ bool StatCache::AddNoObjectCache(string& key)
|
||||
ent->hit_count = 0;
|
||||
ent->isforce = false;
|
||||
ent->noobjcache = true;
|
||||
ent->notruncate = 0L;
|
||||
ent->meta.clear();
|
||||
SetStatCacheTime(ent->cache_date); // Set time.
|
||||
// add
|
||||
@ -430,6 +432,27 @@ bool StatCache::AddNoObjectCache(string& key)
|
||||
return true;
|
||||
}
|
||||
|
||||
void StatCache::ChangeNoTruncateFlag(std::string key, bool no_truncate)
|
||||
{
|
||||
pthread_mutex_lock(&StatCache::stat_cache_lock);
|
||||
|
||||
stat_cache_t::iterator iter = stat_cache.find(key);
|
||||
|
||||
if(stat_cache.end() != iter){
|
||||
stat_cache_entry* ent = iter->second;
|
||||
if(ent){
|
||||
if(no_truncate){
|
||||
++(ent->notruncate);
|
||||
}else{
|
||||
if(0L < ent->notruncate){
|
||||
--(ent->notruncate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&StatCache::stat_cache_lock);
|
||||
}
|
||||
|
||||
bool StatCache::TruncateCache(void)
|
||||
{
|
||||
if(stat_cache.empty()){
|
||||
@ -442,7 +465,7 @@ bool StatCache::TruncateCache(void)
|
||||
if(IsExpireTime){
|
||||
for(stat_cache_t::iterator iter = stat_cache.begin(); iter != stat_cache.end(); ){
|
||||
stat_cache_entry* entry = iter->second;
|
||||
if(!entry || IsExpireStatCacheTime(entry->cache_date, ExpireTime)){
|
||||
if(!entry || (0L < entry->notruncate && IsExpireStatCacheTime(entry->cache_date, ExpireTime))){
|
||||
stat_cache.erase(iter++);
|
||||
}else{
|
||||
++iter;
|
||||
@ -460,6 +483,15 @@ bool StatCache::TruncateCache(void)
|
||||
size_t erase_count= stat_cache.size() - CacheSize + 1;
|
||||
statiterlist_t erase_iters;
|
||||
for(stat_cache_t::iterator iter = stat_cache.begin(); iter != stat_cache.end(); ++iter){
|
||||
// check no truncate
|
||||
stat_cache_entry* ent = iter->second;
|
||||
if(ent && 0L < ent->notruncate){
|
||||
// skip for no truncate entry
|
||||
if(0 < erase_count){
|
||||
--erase_count; // decrement
|
||||
}
|
||||
}
|
||||
// iter is not have notruncate flag
|
||||
erase_iters.push_back(iter);
|
||||
sort(erase_iters.begin(), erase_iters.end(), sort_statiterlist());
|
||||
if(erase_count < erase_iters.size()){
|
||||
|
@ -33,8 +33,9 @@ struct stat_cache_entry {
|
||||
headers_t meta;
|
||||
bool isforce;
|
||||
bool noobjcache; // Flag: cache is no object for no listing.
|
||||
unsigned long notruncate; // 0<: not remove automatically at checking truncate
|
||||
|
||||
stat_cache_entry() : hit_count(0), isforce(false), noobjcache(false) {
|
||||
stat_cache_entry() : hit_count(0), isforce(false), noobjcache(false), notruncate(0L) {
|
||||
memset(&stbuf, 0, sizeof(struct stat));
|
||||
cache_date.tv_sec = 0;
|
||||
cache_date.tv_nsec = 0;
|
||||
@ -112,7 +113,10 @@ class StatCache
|
||||
bool AddNoObjectCache(std::string& key);
|
||||
|
||||
// Add stat cache
|
||||
bool AddStat(std::string& key, headers_t& meta, bool forcedir = false);
|
||||
bool AddStat(std::string& key, headers_t& meta, bool forcedir = false, bool no_truncate = false);
|
||||
|
||||
// Change no truncate flag
|
||||
void ChangeNoTruncateFlag(std::string key, bool no_truncate);
|
||||
|
||||
// Delete stat cache
|
||||
bool DelStat(const char* key);
|
||||
|
28
src/s3fs.cpp
28
src/s3fs.cpp
@ -134,7 +134,7 @@ static s3fs_log_level set_s3fs_log_level(s3fs_log_level level);
|
||||
static s3fs_log_level bumpup_s3fs_log_level(void);
|
||||
static bool is_special_name_folder_object(const char* path);
|
||||
static int chk_dir_object_type(const char* path, string& newpath, string& nowpath, string& nowcache, headers_t* pmeta = NULL, int* pDirType = NULL);
|
||||
static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t* pmeta = NULL, bool overcheck = true, bool* pisforce = NULL);
|
||||
static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t* pmeta = NULL, bool overcheck = true, bool* pisforce = NULL, bool add_no_truncate_cache = false);
|
||||
static int check_object_access(const char* path, int mask, struct stat* pstbuf);
|
||||
static int check_object_owner(const char* path, struct stat* pstbuf);
|
||||
static int check_parent_object_access(const char* path, int mask);
|
||||
@ -389,7 +389,7 @@ static int chk_dir_object_type(const char* path, string& newpath, string& nowpat
|
||||
// 2) "dir/"
|
||||
// 3) "dir_$folder$"
|
||||
//
|
||||
static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t* pmeta, bool overcheck, bool* pisforce)
|
||||
static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t* pmeta, bool overcheck, bool* pisforce, bool add_no_truncate_cache)
|
||||
{
|
||||
int result = -1;
|
||||
struct stat tmpstbuf;
|
||||
@ -426,6 +426,7 @@ static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t
|
||||
(*pisforce) = false;
|
||||
}
|
||||
if(StatCache::getStatCacheData()->GetStat(strpath, pstat, pheader, overcheck, pisforce)){
|
||||
StatCache::getStatCacheData()->ChangeNoTruncateFlag(strpath, add_no_truncate_cache);
|
||||
return 0;
|
||||
}
|
||||
if(StatCache::getStatCacheData()->IsNoObjectCache(strpath)){
|
||||
@ -507,9 +508,16 @@ static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t
|
||||
}
|
||||
|
||||
// Set into cache
|
||||
if(0 != StatCache::getStatCacheData()->GetCacheSize()){
|
||||
//
|
||||
// [NOTE]
|
||||
// When add_no_truncate_cache is true, the stats is always cached.
|
||||
// This cached stats is only removed by DelStat().
|
||||
// This is necessary for the case to access the attribute of opened file.
|
||||
// (ex. getxattr() is called while writing to the opened file.)
|
||||
//
|
||||
if(add_no_truncate_cache || 0 != StatCache::getStatCacheData()->GetCacheSize()){
|
||||
// add into stat cache
|
||||
if(!StatCache::getStatCacheData()->AddStat(strpath, (*pheader), forcedir)){
|
||||
if(!StatCache::getStatCacheData()->AddStat(strpath, (*pheader), forcedir, add_no_truncate_cache)){
|
||||
S3FS_PRN_ERR("failed adding stat cache [path=%s]", strpath.c_str());
|
||||
return -ENOENT;
|
||||
}
|
||||
@ -953,8 +961,9 @@ static int s3fs_create(const char* path, mode_t mode, struct fuse_file_info* fi)
|
||||
|
||||
FdEntity* ent;
|
||||
headers_t meta;
|
||||
get_object_attribute(path, NULL, &meta);
|
||||
get_object_attribute(path, NULL, &meta, true, NULL, true); // no truncate cache
|
||||
if(NULL == (ent = FdManager::get()->Open(path, &meta, 0, -1, false, true))){
|
||||
StatCache::getStatCacheData()->DelStat(path);
|
||||
return -EIO;
|
||||
}
|
||||
fi->fh = ent->GetFd();
|
||||
@ -2039,8 +2048,9 @@ static int s3fs_open(const char* path, struct fuse_file_info* fi)
|
||||
|
||||
FdEntity* ent;
|
||||
headers_t meta;
|
||||
get_object_attribute(path, NULL, &meta);
|
||||
get_object_attribute(path, NULL, &meta, true, NULL, true); // no truncate cache
|
||||
if(NULL == (ent = FdManager::get()->Open(path, &meta, static_cast<ssize_t>(st.st_size), st.st_mtime, false, true))){
|
||||
StatCache::getStatCacheData()->DelStat(path);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -2048,6 +2058,7 @@ static int s3fs_open(const char* path, struct fuse_file_info* fi)
|
||||
if(0 != (result = ent->RowFlush(path, true))){
|
||||
S3FS_PRN_ERR("could not upload file(%s): result=%d", path, result);
|
||||
FdManager::get()->Close(ent);
|
||||
StatCache::getStatCacheData()->DelStat(path);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -2181,6 +2192,11 @@ static int s3fs_release(const char* path, struct fuse_file_info* fi)
|
||||
{
|
||||
S3FS_PRN_INFO("[path=%s][fd=%llu]", path, (unsigned long long)(fi->fh));
|
||||
|
||||
// [NOTE]
|
||||
// All opened file's stats is cached with no truncate flag.
|
||||
// Thus we unset it here.
|
||||
StatCache::getStatCacheData()->ChangeNoTruncateFlag(string(path), false);
|
||||
|
||||
// [NOTICE]
|
||||
// At first, we remove stats cache.
|
||||
// Because fuse does not wait for response from "release" function. :-(
|
||||
|
Loading…
Reference in New Issue
Block a user