in src/s3fs.cpp [2320:2395]
static int s3fs_open(const char* _path, struct fuse_file_info* fi)
{
WTF8_ENCODE(path)
int result;
struct stat st;
bool needs_flush = false;
S3FS_PRN_INFO("[path=%s][flags=0x%x]", path, fi->flags);
if ((fi->flags & O_ACCMODE) == O_RDONLY && fi->flags & O_TRUNC) {
return -EACCES;
}
// [NOTE]
// Delete the Stats cache only if the file is not open.
// If the file is open, the stats cache will not be deleted as
// there are cases where the object does not exist on the server
// and only the Stats cache exists.
//
if(StatCache::getStatCacheData()->HasStat(path)){
if(!FdManager::HasOpenEntityFd(path)){
StatCache::getStatCacheData()->DelStat(path);
}
}
int mask = (O_RDONLY != (fi->flags & O_ACCMODE) ? W_OK : R_OK);
if(0 != (result = check_parent_object_access(path, X_OK))){
return result;
}
result = check_object_access(path, mask, &st);
if(-ENOENT == result){
if(0 != (result = check_parent_object_access(path, W_OK))){
return result;
}
}else if(0 != result){
return result;
}
if((unsigned int)fi->flags & O_TRUNC){
if(0 != st.st_size){
st.st_size = 0;
needs_flush = true;
}
}
if(!S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)){
st.st_mtime = -1;
}
AutoFdEntity autoent;
FdEntity* ent;
headers_t meta;
if(0 != (result = get_object_attribute(path, NULL, &meta, true, NULL, true))){ // no truncate cache
return result;
}
if(NULL == (ent = autoent.Open(path, &meta, st.st_size, st.st_mtime, fi->flags, false, true, false, AutoLock::NONE))){
StatCache::getStatCacheData()->DelStat(path);
return -EIO;
}
if (needs_flush){
time_t now = time(NULL);
struct timespec ts = {now, 0};
ent->SetMCtime(ts, ts);
if(0 != (result = ent->RowFlush(autoent.GetPseudoFd(), path, true))){
S3FS_PRN_ERR("could not upload file(%s): result=%d", path, result);
StatCache::getStatCacheData()->DelStat(path);
return result;
}
}
fi->fh = autoent.Detach(); // KEEP fdentity open;
S3FS_MALLOCTRIM(0);
return 0;
}