static int s3fs_open()

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;
}