Remove uses of AutoLock::ALREADY_LOCKED (#2466)

Instead annotate the methods with REQUIRES so that the caller knows if
they should lock.  For public interfaces, introduce HasLock wrappers.
This simplifies control flow, allows migration to std::mutex, and
eventually will enable use of static lock checking.
This commit is contained in:
Andrew Gaul 2024-06-23 07:54:51 +05:30 committed by GitHub
parent 39c2d8b2a7
commit 2841601ad5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 346 additions and 334 deletions

View File

@ -23,6 +23,9 @@
#include <pthread.h>
// empty annotation to indicate lock requirement
#define REQUIRES(...)
//-------------------------------------------------------------------
// AutoLock Class
//-------------------------------------------------------------------

View File

@ -231,7 +231,7 @@ bool StatCache::GetStat(const std::string& key, struct stat* pst, headers_t* met
if(ent->noobjcache){
if(!IsCacheNoObject){
// need to delete this cache.
DelStat(strpath, AutoLock::ALREADY_LOCKED);
DelStatHasLock(strpath);
}else{
// noobjcache = true means no object.
}
@ -285,7 +285,7 @@ bool StatCache::GetStat(const std::string& key, struct stat* pst, headers_t* met
}
if(is_delete_cache){
DelStat(strpath, AutoLock::ALREADY_LOCKED);
DelStatHasLock(strpath);
}
return false;
}
@ -326,7 +326,7 @@ bool StatCache::IsNoObjectCache(const std::string& key, bool overcheck)
}
if(is_delete_cache){
DelStat(strpath, AutoLock::ALREADY_LOCKED);
DelStatHasLock(strpath);
}
return false;
}
@ -342,13 +342,13 @@ bool StatCache::AddStat(const std::string& key, const headers_t& meta, bool forc
if(stat_cache.end() != stat_cache.find(key)){
// found cache
DelStat(key, AutoLock::ALREADY_LOCKED);
DelStatHasLock(key);
}else{
// check: need to truncate cache
if(stat_cache.size() > CacheSize){
// cppcheck-suppress unmatchedSuppression
// cppcheck-suppress knownConditionTrueFalse
if(!TruncateCache(AutoLock::ALREADY_LOCKED)){
if(!TruncateCache()){
return false;
}
}
@ -388,7 +388,7 @@ bool StatCache::AddStat(const std::string& key, const headers_t& meta, bool forc
if(!S_ISLNK(value.stbuf.st_mode)){
if(symlink_cache.end() != symlink_cache.find(key)){
// if symbolic link cache has key, thus remove it.
DelSymlink(key, AutoLock::ALREADY_LOCKED);
DelSymlinkHasLock(key);
}
}
@ -462,13 +462,13 @@ bool StatCache::AddNoObjectCache(const std::string& key)
if(stat_cache.end() != stat_cache.find(key)){
// found
DelStat(key, AutoLock::ALREADY_LOCKED);
DelStatHasLock(key);
}else{
// check: need to truncate cache
if(stat_cache.size() > CacheSize){
// cppcheck-suppress unmatchedSuppression
// cppcheck-suppress knownConditionTrueFalse
if(!TruncateCache(AutoLock::ALREADY_LOCKED)){
if(!TruncateCache()){
return false;
}
}
@ -489,7 +489,7 @@ bool StatCache::AddNoObjectCache(const std::string& key)
// check symbolic link cache
if(symlink_cache.end() != symlink_cache.find(key)){
// if symbolic link cache has key, thus remove it.
DelSymlink(key, AutoLock::ALREADY_LOCKED);
DelSymlinkHasLock(key);
}
return true;
}
@ -519,10 +519,8 @@ void StatCache::ChangeNoTruncateFlag(const std::string& key, bool no_truncate)
}
}
bool StatCache::TruncateCache(AutoLock::Type locktype)
bool StatCache::TruncateCache()
{
AutoLock lock(&StatCache::stat_cache_lock, locktype);
if(stat_cache.empty()){
return true;
}
@ -577,12 +575,10 @@ bool StatCache::TruncateCache(AutoLock::Type locktype)
return true;
}
bool StatCache::DelStat(const std::string& key, AutoLock::Type locktype)
bool StatCache::DelStatHasLock(const std::string& key)
{
S3FS_PRN_INFO3("delete stat cache entry[path=%s]", key.c_str());
AutoLock lock(&StatCache::stat_cache_lock, locktype);
stat_cache_t::iterator iter;
if(stat_cache.end() != (iter = stat_cache.find(key))){
stat_cache.erase(iter);
@ -636,7 +632,7 @@ bool StatCache::GetSymlink(const std::string& key, std::string& value)
}
if(is_delete_cache){
DelSymlink(strpath, AutoLock::ALREADY_LOCKED);
DelSymlinkHasLock(strpath);
}
return false;
}
@ -652,13 +648,13 @@ bool StatCache::AddSymlink(const std::string& key, const std::string& value)
if(symlink_cache.end() != symlink_cache.find(key)){
// found
DelSymlink(key, AutoLock::ALREADY_LOCKED);
DelSymlinkHasLock(key);
}else{
// check: need to truncate cache
if(symlink_cache.size() > CacheSize){
// cppcheck-suppress unmatchedSuppression
// cppcheck-suppress knownConditionTrueFalse
if(!TruncateSymlink(AutoLock::ALREADY_LOCKED)){
if(!TruncateSymlink()){
return false;
}
}
@ -675,10 +671,8 @@ bool StatCache::AddSymlink(const std::string& key, const std::string& value)
return true;
}
bool StatCache::TruncateSymlink(AutoLock::Type locktype)
bool StatCache::TruncateSymlink()
{
AutoLock lock(&StatCache::stat_cache_lock, locktype);
if(symlink_cache.empty()){
return true;
}
@ -721,12 +715,10 @@ bool StatCache::TruncateSymlink(AutoLock::Type locktype)
return true;
}
bool StatCache::DelSymlink(const std::string& key, AutoLock::Type locktype)
bool StatCache::DelSymlinkHasLock(const std::string& key)
{
S3FS_PRN_INFO3("delete symbolic link cache entry[path=%s]", key.c_str());
AutoLock lock(&StatCache::stat_cache_lock, locktype);
symlink_cache_t::iterator iter;
if(symlink_cache.end() != (iter = symlink_cache.find(key))){
symlink_cache.erase(iter);

View File

@ -112,9 +112,9 @@ class StatCache
void Clear();
bool GetStat(const std::string& key, struct stat* pst, headers_t* meta, bool overcheck, const char* petag, bool* pisforce);
// Truncate stat cache
bool TruncateCache(AutoLock::Type locktype = AutoLock::NONE);
bool TruncateCache() REQUIRES(StatCache::stat_cache_lock);
// Truncate symbolic link cache
bool TruncateSymlink(AutoLock::Type locktype = AutoLock::NONE);
bool TruncateSymlink() REQUIRES(StatCache::stat_cache_lock);
bool AddNotruncateCache(const std::string& key);
bool DelNotruncateCache(const std::string& key);
@ -186,12 +186,21 @@ class StatCache
void ChangeNoTruncateFlag(const std::string& key, bool no_truncate);
// Delete stat cache
bool DelStat(const std::string& key, AutoLock::Type locktype = AutoLock::NONE);
bool DelStat(const std::string& key)
{
AutoLock lock(&StatCache::stat_cache_lock);
return DelStatHasLock(key);
}
bool DelStatHasLock(const std::string& key) REQUIRES(StatCache::stat_cache_lock);
// Cache for symbolic link
bool GetSymlink(const std::string& key, std::string& value);
bool AddSymlink(const std::string& key, const std::string& value);
bool DelSymlink(const std::string& key, AutoLock::Type locktype = AutoLock::NONE);
bool DelSymlink(const std::string& key) {
AutoLock lock(&StatCache::stat_cache_lock);
return DelSymlinkHasLock(key);
}
bool DelSymlinkHasLock(const std::string& key);
// Cache for Notruncate file
bool GetNotruncateCache(const std::string& parentdir, notruncate_filelist_t& list);

View File

@ -2004,7 +2004,7 @@ S3fsCurl::~S3fsCurl()
DestroyCurlHandle();
}
bool S3fsCurl::ResetHandle(AutoLock::Type locktype)
bool S3fsCurl::ResetHandle()
{
bool run_once;
{
@ -2131,7 +2131,6 @@ bool S3fsCurl::ResetHandle(AutoLock::Type locktype)
}
}
AutoLock lock(&S3fsCurl::curl_handles_lock, locktype);
S3fsCurl::curl_times[hCurl] = time(nullptr);
S3fsCurl::curl_progress[hCurl] = progress_t(-1, -1);
@ -2143,7 +2142,7 @@ bool S3fsCurl::CreateCurlHandle(bool only_pool, bool remake)
AutoLock lock(&S3fsCurl::curl_handles_lock);
if(hCurl && remake){
if(!DestroyCurlHandle(false, true, AutoLock::ALREADY_LOCKED)){
if(!DestroyCurlHandleHasLock(false, true)){
S3FS_PRN_ERR("could not destroy handle.");
return false;
}
@ -2163,12 +2162,18 @@ bool S3fsCurl::CreateCurlHandle(bool only_pool, bool remake)
}
}
}
ResetHandle(AutoLock::ALREADY_LOCKED);
ResetHandle();
return true;
}
bool S3fsCurl::DestroyCurlHandle(bool restore_pool, bool clear_internal_data, AutoLock::Type locktype)
bool S3fsCurl::DestroyCurlHandle(bool restore_pool, bool clear_internal_data)
{
AutoLock lock(&S3fsCurl::curl_handles_lock);
return DestroyCurlHandleHasLock(restore_pool, clear_internal_data);
}
bool S3fsCurl::DestroyCurlHandleHasLock(bool restore_pool, bool clear_internal_data)
{
// [NOTE]
// If type is REQTYPE::IAMCRED or REQTYPE::IAMROLE, do not clear type.
@ -2179,8 +2184,6 @@ bool S3fsCurl::DestroyCurlHandle(bool restore_pool, bool clear_internal_data, Au
type = REQTYPE::UNSET;
}
AutoLock lock(&S3fsCurl::curl_handles_lock, locktype);
if(clear_internal_data){
ClearInternalData();
}
@ -2298,7 +2301,10 @@ bool S3fsCurl::RemakeHandle()
partdata.size = b_partdata_size;
// reset handle
ResetHandle();
{
AutoLock lock(&S3fsCurl::curl_handles_lock);
ResetHandle();
}
// set options
switch(type){

View File

@ -258,7 +258,7 @@ class S3fsCurl
static int RawCurlDebugFunc(const CURL* hcurl, curl_infotype type, char* data, size_t size, void* userptr, curl_infotype datatype);
// methods
bool ResetHandle(AutoLock::Type locktype = AutoLock::NONE);
bool ResetHandle() REQUIRES(&S3fsCurl::curl_handles_lock);
bool RemakeHandle();
bool ClearInternalData();
void insertV4Headers(const std::string& access_key_id, const std::string& secret_access_key, const std::string& access_token);
@ -354,7 +354,8 @@ class S3fsCurl
// methods
bool CreateCurlHandle(bool only_pool = false, bool remake = false);
bool DestroyCurlHandle(bool restore_pool = true, bool clear_internal_data = true, AutoLock::Type locktype = AutoLock::NONE);
bool DestroyCurlHandle(bool restore_pool = true, bool clear_internal_data = true);
bool DestroyCurlHandleHasLock(bool restore_pool = true, bool clear_internal_data = true) REQUIRES(S3fsCurl::curl_handles_lock);
bool GetIAMCredentials(const char* cred_url, const char* iam_v2_token, const char* ibm_secret_access_key, std::string& response);
bool GetIAMRoleFromMetaData(const char* cred_url, const char* iam_v2_token, std::string& token);

View File

@ -433,7 +433,7 @@ bool FdManager::HasOpenEntityFd(const char* path)
const FdEntity* ent;
int fd = -1;
if(nullptr == (ent = FdManager::singleton.GetFdEntity(path, fd, false, AutoLock::ALREADY_LOCKED))){
if(nullptr == (ent = FdManager::singleton.GetFdEntityHasLock(path, fd, false))){
return false;
}
return (0 < ent->GetOpenCount());
@ -509,14 +509,13 @@ FdManager::~FdManager()
}
}
FdEntity* FdManager::GetFdEntity(const char* path, int& existfd, bool newfd, AutoLock::Type locktype)
FdEntity* FdManager::GetFdEntityHasLock(const char* path, int& existfd, bool newfd)
{
S3FS_PRN_INFO3("[path=%s][pseudo_fd=%d]", SAFESTRPTR(path), existfd);
if(!path || '\0' == path[0]){
return nullptr;
}
AutoLock auto_lock(&FdManager::fd_manager_lock, locktype);
fdent_map_t::iterator iter = fent.find(path);
if(fent.end() != iter && iter->second){
@ -525,11 +524,13 @@ FdEntity* FdManager::GetFdEntity(const char* path, int& existfd, bool newfd, Aut
existfd = iter->second->OpenPseudoFd(O_RDWR); // [NOTE] O_RDWR flags
}
return iter->second.get();
}else if(iter->second->FindPseudoFd(existfd)){
if(newfd){
existfd = iter->second->Dup(existfd);
}else{
if(iter->second->FindPseudoFd(existfd)){
if(newfd){
existfd = iter->second->Dup(existfd);
}
return iter->second.get();
}
return iter->second.get();
}
}
@ -562,7 +563,7 @@ FdEntity* FdManager::GetFdEntity(const char* path, int& existfd, bool newfd, Aut
return nullptr;
}
FdEntity* FdManager::Open(int& fd, const char* path, const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags, bool force_tmpfile, bool is_create, bool ignore_modify, AutoLock::Type type)
FdEntity* FdManager::Open(int& fd, const char* path, const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags, bool force_tmpfile, bool is_create, bool ignore_modify)
{
S3FS_PRN_DBG("[path=%s][size=%lld][ts_mctime=%s][flags=0x%x][force_tmpfile=%s][create=%s][ignore_modify=%s]", SAFESTRPTR(path), static_cast<long long>(size), str(ts_mctime).c_str(), flags, (force_tmpfile ? "yes" : "no"), (is_create ? "yes" : "no"), (ignore_modify ? "yes" : "no"));
@ -606,7 +607,7 @@ FdEntity* FdManager::Open(int& fd, const char* path, const headers_t* pmeta, off
}
// (re)open
if(0 > (fd = ent->Open(pmeta, size, ts_mctime, flags, type))){
if(0 > (fd = ent->Open(pmeta, size, ts_mctime, flags))){
S3FS_PRN_ERR("failed to (re)open and create new pseudo fd for path(%s).", path);
return nullptr;
}
@ -623,7 +624,7 @@ FdEntity* FdManager::Open(int& fd, const char* path, const headers_t* pmeta, off
std::unique_ptr<FdEntity> ent(new FdEntity(path, cache_path.c_str()));
// open
if(0 > (fd = ent->Open(pmeta, size, ts_mctime, flags, type))){
if(0 > (fd = ent->Open(pmeta, size, ts_mctime, flags))){
S3FS_PRN_ERR("failed to open and create new pseudo fd for path(%s) errno:%d.", path, fd);
return nullptr;
}
@ -674,7 +675,7 @@ FdEntity* FdManager::OpenExistFdEntity(const char* path, int& fd, int flags)
S3FS_PRN_DBG("[path=%s][flags=0x%x]", SAFESTRPTR(path), flags);
// search entity by path, and create pseudo fd
FdEntity* ent = Open(fd, path, nullptr, -1, S3FS_OMIT_TS, flags, false, false, false, AutoLock::NONE);
FdEntity* ent = Open(fd, path, nullptr, -1, S3FS_OMIT_TS, flags, false, false, false);
if(!ent){
// Not found entity
return nullptr;

View File

@ -94,8 +94,12 @@ class FdManager
static off_t GetTotalDiskSpaceByRatio(int ratio);
// Return FdEntity associated with path, returning nullptr on error. This operation increments the reference count; callers must decrement via Close after use.
FdEntity* GetFdEntity(const char* path, int& existfd, bool newfd = true, AutoLock::Type locktype = AutoLock::NONE);
FdEntity* Open(int& fd, const char* path, const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags, bool force_tmpfile, bool is_create, bool ignore_modify, AutoLock::Type type);
FdEntity* GetFdEntity(const char* path, int& existfd, bool newfd = true) {
AutoLock auto_lock(&FdManager::fd_manager_lock);
return GetFdEntityHasLock(path, existfd, newfd);
}
FdEntity* GetFdEntityHasLock(const char* path, int& existfd, bool newfd = true) REQUIRES(FdManager::fd_manager_lock);
FdEntity* Open(int& fd, const char* path, const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags, bool force_tmpfile, bool is_create, bool ignore_modify) REQUIRES(FdManager::fd_manager_lock);
FdEntity* GetExistFdEntity(const char* path, int existfd = -1);
FdEntity* OpenExistFdEntity(const char* path, int& fd, int flags = O_RDONLY);
void Rename(const std::string &from, const std::string &to);

View File

@ -78,11 +78,11 @@ FdEntity* AutoFdEntity::Attach(const char* path, int existfd)
return pFdEntity;
}
FdEntity* AutoFdEntity::Open(const char* path, const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags, bool force_tmpfile, bool is_create, bool ignore_modify, AutoLock::Type type, int* error)
FdEntity* AutoFdEntity::Open(const char* path, const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags, bool force_tmpfile, bool is_create, bool ignore_modify, int* error)
{
Close();
if(nullptr == (pFdEntity = FdManager::get()->Open(pseudo_fd, path, pmeta, size, ts_mctime, flags, force_tmpfile, is_create, ignore_modify, type))){
if(nullptr == (pFdEntity = FdManager::get()->Open(pseudo_fd, path, pmeta, size, ts_mctime, flags, force_tmpfile, is_create, ignore_modify))){
if(error){
*error = pseudo_fd;
}

View File

@ -57,7 +57,7 @@ class AutoFdEntity
FdEntity* Attach(const char* path, int existfd);
int GetPseudoFd() const { return pseudo_fd; }
FdEntity* Open(const char* path, const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags, bool force_tmpfile, bool is_create, bool ignore_modify, AutoLock::Type type, int* error = nullptr);
FdEntity* Open(const char* path, const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags, bool force_tmpfile, bool is_create, bool ignore_modify, int* error = nullptr) REQUIRES(FdManager::fd_manager_lock);
FdEntity* GetExistFdEntity(const char* path, int existfd = -1);
FdEntity* OpenExistFdEntity(const char* path, int flags = O_RDONLY);
};

View File

@ -223,7 +223,7 @@ void FdEntity::Close(int fd)
}
// check pseudo fd count
if(-1 != physical_fd && 0 == GetOpenCount(AutoLock::ALREADY_LOCKED)){
if(-1 != physical_fd && 0 == GetOpenCountHasLock()){
AutoLock auto_data_lock(&fdent_data_lock);
if(!cachepath.empty()){
// [NOTE]
@ -255,10 +255,8 @@ void FdEntity::Close(int fd)
}
}
int FdEntity::Dup(int fd, AutoLock::Type locktype)
int FdEntity::DupWithLock(int fd)
{
AutoLock auto_lock(&fdent_lock, locktype);
S3FS_PRN_DBG("[path=%s][pseudo_fd=%d][physical_fd=%d][pseudo fd count=%zu]", path.c_str(), fd, physical_fd, pseudo_fd_map.size());
if(-1 == physical_fd){
@ -277,9 +275,9 @@ int FdEntity::Dup(int fd, AutoLock::Type locktype)
return pseudo_fd;
}
int FdEntity::OpenPseudoFd(int flags, AutoLock::Type locktype)
int FdEntity::OpenPseudoFd(int flags)
{
AutoLock auto_lock(&fdent_lock, locktype);
AutoLock auto_lock(&fdent_lock);
S3FS_PRN_DBG("[path=%s][physical_fd=%d][pseudo fd count=%zu]", path.c_str(), physical_fd, pseudo_fd_map.size());
@ -293,10 +291,8 @@ int FdEntity::OpenPseudoFd(int flags, AutoLock::Type locktype)
return pseudo_fd;
}
int FdEntity::GetOpenCount(AutoLock::Type locktype) const
int FdEntity::GetOpenCountHasLock() const
{
AutoLock auto_lock(&fdent_lock, locktype);
return static_cast<int>(pseudo_fd_map.size());
}
@ -358,10 +354,8 @@ int FdEntity::OpenMirrorFile()
return mirrorfd;
}
bool FdEntity::FindPseudoFd(int fd, AutoLock::Type locktype) const
bool FdEntity::FindPseudoFdWithLock(int fd) const
{
AutoLock auto_lock(&fdent_lock, locktype);
if(-1 == fd){
return false;
}
@ -371,10 +365,8 @@ bool FdEntity::FindPseudoFd(int fd, AutoLock::Type locktype) const
return true;
}
PseudoFdInfo* FdEntity::CheckPseudoFdFlags(int fd, bool writable, AutoLock::Type locktype)
PseudoFdInfo* FdEntity::CheckPseudoFdFlags(int fd, bool writable)
{
AutoLock auto_lock(&fdent_lock, locktype);
if(-1 == fd){
return nullptr;
}
@ -394,10 +386,8 @@ PseudoFdInfo* FdEntity::CheckPseudoFdFlags(int fd, bool writable, AutoLock::Type
return iter->second.get();
}
bool FdEntity::IsUploading(AutoLock::Type locktype)
bool FdEntity::IsUploading()
{
AutoLock auto_lock(&fdent_lock, locktype);
for(fdinfo_map_t::const_iterator iter = pseudo_fd_map.begin(); iter != pseudo_fd_map.end(); ++iter){
const PseudoFdInfo* ppseudoinfo = iter->second.get();
if(ppseudoinfo && ppseudoinfo->IsUploading()){
@ -417,18 +407,11 @@ bool FdEntity::IsUploading(AutoLock::Type locktype)
// This is similar to utimens operation.
// You can use "S3FS_OMIT_TS" global variable for UTIME_OMIT.
//
int FdEntity::Open(const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags, AutoLock::Type type)
int FdEntity::Open(const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags)
{
AutoLock auto_lock(&fdent_lock, type);
S3FS_PRN_DBG("[path=%s][physical_fd=%d][size=%lld][ts_mctime=%s][flags=0x%x]", path.c_str(), physical_fd, static_cast<long long>(size), str(ts_mctime).c_str(), flags);
if (!auto_lock.isLockAcquired()) {
// had to wait for fd lock, return
S3FS_PRN_ERR("Could not get lock.");
return -EIO;
}
AutoLock lock(&fdent_lock);
AutoLock auto_data_lock(&fdent_data_lock);
// [NOTE]
@ -658,7 +641,7 @@ int FdEntity::Open(const headers_t* pmeta, off_t size, const struct timespec& ts
// set mtime and ctime(set "x-amz-meta-mtime" and "x-amz-meta-ctime" in orgmeta)
if(UTIME_OMIT != ts_mctime.tv_nsec){
if(0 != SetMCtime(ts_mctime, ts_mctime, AutoLock::ALREADY_LOCKED)){
if(0 != SetMCtimeHasLock(ts_mctime, ts_mctime)){
S3FS_PRN_ERR("failed to set mtime/ctime. errno(%d)", errno);
fclose(pfile);
pfile = nullptr;
@ -699,7 +682,7 @@ bool FdEntity::LoadAll(int fd, headers_t* pmeta, off_t* size, bool force_load)
S3FS_PRN_INFO3("[path=%s][pseudo_fd=%d][physical_fd=%d]", path.c_str(), fd, physical_fd);
if(-1 == physical_fd || !FindPseudoFd(fd, AutoLock::ALREADY_LOCKED)){
if(-1 == physical_fd || !FindPseudoFdWithLock(fd)){
S3FS_PRN_ERR("pseudo_fd(%d) and physical_fd(%d) for path(%s) is not opened yet", fd, physical_fd, path.c_str());
return false;
}
@ -713,7 +696,7 @@ bool FdEntity::LoadAll(int fd, headers_t* pmeta, off_t* size, bool force_load)
// TODO: possibly do background for delay loading
//
int result;
if(0 != (result = Load(/*start=*/ 0, /*size=*/ 0, AutoLock::ALREADY_LOCKED))){
if(0 != (result = Load(/*start=*/ 0, /*size=*/ 0))){
S3FS_PRN_ERR("could not download, result(%d)", result);
return false;
}
@ -780,9 +763,8 @@ bool FdEntity::IsModified() const
return pagelist.IsModified();
}
bool FdEntity::GetStats(struct stat& st, AutoLock::Type locktype) const
bool FdEntity::GetStatsHasLock(struct stat& st) const
{
AutoLock auto_lock(&fdent_lock, locktype);
if(-1 == physical_fd){
return false;
}
@ -795,10 +777,8 @@ bool FdEntity::GetStats(struct stat& st, AutoLock::Type locktype) const
return true;
}
int FdEntity::SetCtime(struct timespec time, AutoLock::Type locktype)
int FdEntity::SetCtimeHasLock(struct timespec time)
{
AutoLock auto_lock(&fdent_lock, locktype);
S3FS_PRN_INFO3("[path=%s][physical_fd=%d][time=%s]", path.c_str(), physical_fd, str(time).c_str());
if(-1 == time.tv_sec){
@ -808,10 +788,8 @@ int FdEntity::SetCtime(struct timespec time, AutoLock::Type locktype)
return 0;
}
int FdEntity::SetAtime(struct timespec time, AutoLock::Type locktype)
int FdEntity::SetAtimeHasLock(struct timespec time)
{
AutoLock auto_lock(&fdent_lock, locktype);
S3FS_PRN_INFO3("[path=%s][physical_fd=%d][time=%s]", path.c_str(), physical_fd, str(time).c_str());
if(-1 == time.tv_sec){
@ -824,10 +802,8 @@ int FdEntity::SetAtime(struct timespec time, AutoLock::Type locktype)
// [NOTE]
// This method updates mtime as well as ctime.
//
int FdEntity::SetMCtime(struct timespec mtime, struct timespec ctime, AutoLock::Type locktype)
int FdEntity::SetMCtimeHasLock(struct timespec mtime, struct timespec ctime)
{
AutoLock auto_lock(&fdent_lock, locktype);
S3FS_PRN_INFO3("[path=%s][physical_fd=%d][mtime=%s][ctime=%s]", path.c_str(), physical_fd, str(mtime).c_str(), str(ctime).c_str());
if(mtime.tv_sec < 0 || ctime.tv_sec < 0){
@ -867,7 +843,7 @@ bool FdEntity::UpdateCtime()
{
AutoLock auto_lock(&fdent_lock);
struct stat st;
if(!GetStats(st, AutoLock::ALREADY_LOCKED)){
if(!GetStatsHasLock(st)){
return false;
}
@ -880,7 +856,7 @@ bool FdEntity::UpdateAtime()
{
AutoLock auto_lock(&fdent_lock);
struct stat st;
if(!GetStats(st, AutoLock::ALREADY_LOCKED)){
if(!GetStatsHasLock(st)){
return false;
}
@ -904,7 +880,7 @@ bool FdEntity::UpdateMtime(bool clear_holding_mtime)
// overwritten.
//
if(clear_holding_mtime){
if(!ClearHoldingMtime(AutoLock::ALREADY_LOCKED)){
if(!ClearHoldingMtime()){
return false;
}
// [NOTE]
@ -917,7 +893,7 @@ bool FdEntity::UpdateMtime(bool clear_holding_mtime)
}
}else{
struct stat st;
if(!GetStats(st, AutoLock::ALREADY_LOCKED)){
if(!GetStatsHasLock(st)){
return false;
}
orgmeta["x-amz-meta-mtime"] = str_stat_time(st, stat_time_type::MTIME);
@ -925,12 +901,12 @@ bool FdEntity::UpdateMtime(bool clear_holding_mtime)
return true;
}
bool FdEntity::SetHoldingMtime(struct timespec mtime, AutoLock::Type locktype)
bool FdEntity::SetHoldingMtime(struct timespec mtime)
{
AutoLock auto_lock(&fdent_lock, locktype);
S3FS_PRN_INFO3("[path=%s][physical_fd=%d][mtime=%s]", path.c_str(), physical_fd, str(mtime).c_str());
AutoLock lock(&fdent_lock);
if(mtime.tv_sec < 0){
return false;
}
@ -938,15 +914,13 @@ bool FdEntity::SetHoldingMtime(struct timespec mtime, AutoLock::Type locktype)
return true;
}
bool FdEntity::ClearHoldingMtime(AutoLock::Type locktype)
bool FdEntity::ClearHoldingMtime()
{
AutoLock auto_lock(&fdent_lock, locktype);
if(holding_mtime.tv_sec < 0){
return false;
}
struct stat st;
if(!GetStats(st, AutoLock::ALREADY_LOCKED)){
if(!GetStatsHasLock(st)){
return false;
}
if(-1 != physical_fd){
@ -1017,23 +991,20 @@ bool FdEntity::SetXattr(const std::string& xattr)
return true;
}
bool FdEntity::SetMode(mode_t mode)
bool FdEntity::SetModeHasLock(mode_t mode)
{
AutoLock auto_lock(&fdent_lock);
orgmeta["x-amz-meta-mode"] = std::to_string(mode);
return true;
}
bool FdEntity::SetUId(uid_t uid)
bool FdEntity::SetUIdHasLock(uid_t uid)
{
AutoLock auto_lock(&fdent_lock);
orgmeta["x-amz-meta-uid"] = std::to_string(uid);
return true;
}
bool FdEntity::SetGId(gid_t gid)
bool FdEntity::SetGIdHasLock(gid_t gid)
{
AutoLock auto_lock(&fdent_lock);
orgmeta["x-amz-meta-gid"] = std::to_string(gid);
return true;
}
@ -1043,7 +1014,7 @@ bool FdEntity::SetContentType(const char* path)
if(!path){
return false;
}
AutoLock auto_lock(&fdent_lock);
AutoLock lock(&fdent_lock);
orgmeta["Content-Type"] = S3fsCurl::LookupMimeType(path);
return true;
}
@ -1074,16 +1045,13 @@ bool FdEntity::SetAllStatus(bool is_loaded)
return true;
}
int FdEntity::Load(off_t start, off_t size, AutoLock::Type type, bool is_modified_flag)
int FdEntity::Load(off_t start, off_t size, bool is_modified_flag)
{
AutoLock auto_lock(&fdent_lock, type);
S3FS_PRN_DBG("[path=%s][physical_fd=%d][offset=%lld][size=%lld]", path.c_str(), physical_fd, static_cast<long long int>(start), static_cast<long long int>(size));
if(-1 == physical_fd){
return -EBADF;
}
AutoLock auto_data_lock(&fdent_data_lock, type);
int result = 0;
@ -1410,10 +1378,8 @@ off_t FdEntity::BytesModified()
// Files smaller than the minimum part size will not be multipart uploaded,
// but will be uploaded as single part(normally).
//
int FdEntity::RowFlush(int fd, const char* tpath, AutoLock::Type type, bool force_sync)
int FdEntity::RowFlushHasLock(int fd, const char* tpath, bool force_sync)
{
AutoLock auto_lock(&fdent_lock, type);
S3FS_PRN_INFO3("[tpath=%s][path=%s][pseudo_fd=%d][physical_fd=%d]", SAFESTRPTR(tpath), path.c_str(), fd, physical_fd);
if(-1 == physical_fd){
@ -1446,7 +1412,7 @@ int FdEntity::RowFlush(int fd, const char* tpath, AutoLock::Type type, bool forc
// No multipart upload
if(!force_sync && !pagelist.IsModified()){
// for only push pending headers
result = UploadPending(-1, AutoLock::ALREADY_LOCKED);
result = UploadPendingHasLock(-1);
}else{
result = RowFlushNoMultipart(pseudo_obj, tpath);
}
@ -1505,7 +1471,7 @@ int FdEntity::RowFlushNoMultipart(const PseudoFdInfo* pseudo_obj, const char* tp
FdManager::FreeReservedDiskSpace(restsize);
// Always load all uninitialized area
if(0 != (result = Load(/*start=*/ 0, /*size=*/ 0, AutoLock::ALREADY_LOCKED))){
if(0 != (result = Load(/*start=*/ 0, /*size=*/ 0))){
S3FS_PRN_ERR("failed to upload all area(errno=%d)", result);
return result;
}
@ -1578,7 +1544,7 @@ int FdEntity::RowFlushMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
FdManager::FreeReservedDiskSpace(restsize);
// Load all uninitialized area(no mix multipart uploading)
if(0 != (result = Load(/*start=*/ 0, /*size=*/ 0, AutoLock::ALREADY_LOCKED))){
if(0 != (result = Load(/*start=*/ 0, /*size=*/ 0))){
S3FS_PRN_ERR("failed to upload all area(errno=%d)", result);
return result;
}
@ -1633,7 +1599,7 @@ int FdEntity::RowFlushMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
S3FS_PRN_ERR("failed to truncate file(physical_fd=%d) to zero, but continue...", physical_fd);
}
// put pending headers or create new file
if(0 != (result = UploadPending(-1, AutoLock::ALREADY_LOCKED))){
if(0 != (result = UploadPendingHasLock(-1))){
return result;
}
}
@ -1710,7 +1676,7 @@ int FdEntity::RowFlushMixMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
// [TODO] should use parallel downloading
//
for(fdpage_list_t::const_iterator iter = dlpages.begin(); iter != dlpages.end(); ++iter){
if(0 != (result = Load(iter->offset, iter->bytes, AutoLock::ALREADY_LOCKED, /*is_modified_flag=*/ true))){ // set loaded and modified flag
if(0 != (result = Load(iter->offset, iter->bytes, /*is_modified_flag=*/ true))){ // set loaded and modified flag
S3FS_PRN_ERR("failed to get parts(start=%lld, size=%lld) before uploading.", static_cast<long long int>(iter->offset), static_cast<long long int>(iter->bytes));
return result;
}
@ -1723,7 +1689,7 @@ int FdEntity::RowFlushMixMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
// normal uploading (too small part size)
// If there are unloaded pages, they are loaded at here.
if(0 != (result = Load(/*start=*/ 0, /*size=*/ 0, AutoLock::ALREADY_LOCKED))){
if(0 != (result = Load(/*start=*/ 0, /*size=*/ 0))){
S3FS_PRN_ERR("failed to load parts before uploading object(%d)", result);
return result;
}
@ -1761,7 +1727,7 @@ int FdEntity::RowFlushMixMultipart(PseudoFdInfo* pseudo_obj, const char* tpath)
S3FS_PRN_ERR("failed to truncate file(physical_fd=%d) to zero, but continue...", physical_fd);
}
// put pending headers or create new file
if(0 != (result = UploadPending(-1, AutoLock::ALREADY_LOCKED))){
if(0 != (result = UploadPendingHasLock(-1))){
return result;
}
}
@ -1798,7 +1764,7 @@ int FdEntity::RowFlushStreamMultipart(PseudoFdInfo* pseudo_obj, const char* tpat
}
// If there are unloaded pages, they are loaded at here.
if(0 != (result = Load(/*start=*/ 0, /*size=*/ 0, AutoLock::ALREADY_LOCKED))){
if(0 != (result = Load(/*start=*/ 0, /*size=*/ 0))){
S3FS_PRN_ERR("failed to load parts before uploading object(%d)", result);
return result;
}
@ -1857,7 +1823,7 @@ int FdEntity::RowFlushStreamMultipart(PseudoFdInfo* pseudo_obj, const char* tpat
// Execute in parallel downloading with multiple thread.
//
for(mp_part_list_t::const_iterator download_iter = to_download_list.begin(); download_iter != to_download_list.end(); ++download_iter){
if(0 != (result = Load(download_iter->start, download_iter->size, AutoLock::ALREADY_LOCKED))){
if(0 != (result = Load(download_iter->start, download_iter->size))){
break;
}
}
@ -1969,7 +1935,7 @@ int FdEntity::RowFlushStreamMultipart(PseudoFdInfo* pseudo_obj, const char* tpat
pseudo_obj->ClearUploadInfo(); // clear multipart upload info
// put pending headers or create new file
if(0 != (result = UploadPending(-1, AutoLock::ALREADY_LOCKED))){
if(0 != (result = UploadPendingHasLock(-1))){
return result;
}
}
@ -2012,12 +1978,13 @@ ssize_t FdEntity::Read(int fd, char* bytes, off_t start, size_t size, bool force
{
S3FS_PRN_DBG("[path=%s][pseudo_fd=%d][physical_fd=%d][offset=%lld][size=%zu]", path.c_str(), fd, physical_fd, static_cast<long long int>(start), size);
AutoLock auto_lock(&fdent_lock);
if(-1 == physical_fd || nullptr == CheckPseudoFdFlags(fd, false)){
S3FS_PRN_DBG("pseudo_fd(%d) to physical_fd(%d) for path(%s) is not opened or not readable", fd, physical_fd, path.c_str());
return -EBADF;
}
AutoLock auto_lock(&fdent_lock);
AutoLock auto_lock2(&fdent_data_lock);
if(force_load){
@ -2052,7 +2019,7 @@ ssize_t FdEntity::Read(int fd, char* bytes, off_t start, size_t size, bool force
// Loading
int result = 0;
if(0 < size){
result = Load(start, load_size, AutoLock::ALREADY_LOCKED);
result = Load(start, load_size);
}
FdManager::FreeReservedDiskSpace(load_size);
@ -2075,6 +2042,7 @@ ssize_t FdEntity::Write(int fd, const char* bytes, off_t start, size_t size)
{
S3FS_PRN_DBG("[path=%s][pseudo_fd=%d][physical_fd=%d][offset=%lld][size=%zu]", path.c_str(), fd, physical_fd, static_cast<long long int>(start), size);
AutoLock auto_lock(&fdent_lock);
PseudoFdInfo* pseudo_obj = nullptr;
if(-1 == physical_fd || nullptr == (pseudo_obj = CheckPseudoFdFlags(fd, false))){
S3FS_PRN_ERR("pseudo_fd(%d) to physical_fd(%d) for path(%s) is not opened or not writable", fd, physical_fd, path.c_str());
@ -2085,7 +2053,6 @@ ssize_t FdEntity::Write(int fd, const char* bytes, off_t start, size_t size)
if(FdManager::IsCacheDir() && !FdManager::IsSafeDiskSpace(nullptr, size)){
FdManager::get()->CleanupCacheDir();
}
AutoLock auto_lock(&fdent_lock);
AutoLock auto_lock2(&fdent_data_lock);
// check file size
@ -2152,7 +2119,7 @@ ssize_t FdEntity::WriteNoMultipart(const PseudoFdInfo* pseudo_obj, const char* b
// Load uninitialized area which starts from 0 to (start + size) before writing.
if(0 < start){
result = Load(0, start, AutoLock::ALREADY_LOCKED);
result = Load(0, start);
}
FdManager::FreeReservedDiskSpace(restsize);
@ -2174,7 +2141,7 @@ ssize_t FdEntity::WriteNoMultipart(const PseudoFdInfo* pseudo_obj, const char* b
// Load uninitialized area which starts from (start + size) to EOF after writing.
if(pagelist.Size() > start + static_cast<off_t>(size)){
result = Load(start + size, pagelist.Size(), AutoLock::ALREADY_LOCKED);
result = Load(start + size, pagelist.Size());
if(0 != result){
S3FS_PRN_ERR("failed to load uninitialized area after writing(errno=%d)", result);
return result;
@ -2206,7 +2173,7 @@ ssize_t FdEntity::WriteMultipart(PseudoFdInfo* pseudo_obj, const char* bytes, of
// Load uninitialized area which starts from 0 to (start + size) before writing.
if(0 < start){
result = Load(0, start, AutoLock::ALREADY_LOCKED);
result = Load(0, start);
}
FdManager::FreeReservedDiskSpace(restsize);
@ -2248,7 +2215,7 @@ ssize_t FdEntity::WriteMultipart(PseudoFdInfo* pseudo_obj, const char* bytes, of
// Load uninitialized area which starts from (start + size) to EOF after writing.
if(pagelist.Size() > start + static_cast<off_t>(size)){
result = Load(start + size, pagelist.Size(), AutoLock::ALREADY_LOCKED);
result = Load(start + size, pagelist.Size());
if(0 != result){
S3FS_PRN_ERR("failed to load uninitialized area after writing(errno=%d)", result);
return result;
@ -2436,14 +2403,14 @@ bool FdEntity::MergeOrgMeta(headers_t& updatemeta)
struct timespec ctime = get_ctime(updatemeta, false); // not overcheck
struct timespec atime = get_atime(updatemeta, false); // not overcheck
if(0 <= mtime.tv_sec){
SetMCtime(mtime, (ctime.tv_sec < 0 ? mtime : ctime), AutoLock::ALREADY_LOCKED);
SetMCtimeHasLock(mtime, (ctime.tv_sec < 0 ? mtime : ctime));
}
if(0 <= atime.tv_sec){
SetAtime(atime, AutoLock::ALREADY_LOCKED);
SetAtimeHasLock(atime);
}
AutoLock auto_lock2(&fdent_data_lock);
if(pending_status_t::NO_UPDATE_PENDING == pending_status && (IsUploading(AutoLock::ALREADY_LOCKED) || pagelist.IsModified())){
if(pending_status_t::NO_UPDATE_PENDING == pending_status && (IsUploading() || pagelist.IsModified())){
pending_status = pending_status_t::UPDATE_META_PENDING;
}
@ -2453,9 +2420,8 @@ bool FdEntity::MergeOrgMeta(headers_t& updatemeta)
// global function in s3fs.cpp
int put_headers(const char* path, headers_t& meta, bool is_copy, bool use_st_size = true);
int FdEntity::UploadPending(int fd, AutoLock::Type type)
int FdEntity::UploadPendingHasLock(int fd)
{
AutoLock auto_lock(&fdent_lock, type);
int result;
if(pending_status_t::NO_UPDATE_PENDING == pending_status){
@ -2480,7 +2446,7 @@ int FdEntity::UploadPending(int fd, AutoLock::Type type)
S3FS_PRN_ERR("could not create a new file(%s), because fd is not specified.", path.c_str());
result = -EBADF;
}else{
result = Flush(fd, AutoLock::ALREADY_LOCKED, true);
result = FlushHasLock(fd, true);
if(0 != result){
S3FS_PRN_ERR("failed to flush for file(%s) by(%d).", path.c_str(), result);
}else{

View File

@ -77,8 +77,8 @@ class FdEntity
ino_t GetInode() const;
int OpenMirrorFile();
int NoCacheLoadAndPost(PseudoFdInfo* pseudo_obj, off_t start = 0, off_t size = 0); // size=0 means loading to end
PseudoFdInfo* CheckPseudoFdFlags(int fd, bool writable, AutoLock::Type locktype = AutoLock::NONE);
bool IsUploading(AutoLock::Type locktype = AutoLock::NONE);
PseudoFdInfo* CheckPseudoFdFlags(int fd, bool writable) REQUIRES(FdEntity::fdent_lock);
bool IsUploading() REQUIRES(FdEntity::fdent_lock);
bool SetAllStatus(bool is_loaded); // [NOTE] not locking
bool SetAllStatusUnloaded() { return SetAllStatus(false); }
int NoCachePreMultipartPost(PseudoFdInfo* pseudo_obj);
@ -113,43 +113,97 @@ class FdEntity
FdEntity& operator=(FdEntity&&) = delete;
void Close(int fd);
// TODO: should this require a lock?
bool IsOpen() const { return (-1 != physical_fd); }
bool FindPseudoFd(int fd, AutoLock::Type locktype = AutoLock::NONE) const;
int Open(const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags, AutoLock::Type type);
bool FindPseudoFd(int fd) const {
AutoLock lock(&fdent_lock);
return FindPseudoFdWithLock(fd);
}
bool FindPseudoFdWithLock(int fd) const REQUIRES(FdEntity::fdent_lock);
int Open(const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags) REQUIRES(FdEntity::fdent_lock);
bool LoadAll(int fd, headers_t* pmeta = nullptr, off_t* size = nullptr, bool force_load = false);
int Dup(int fd, AutoLock::Type locktype = AutoLock::NONE);
int OpenPseudoFd(int flags = O_RDONLY, AutoLock::Type locktype = AutoLock::NONE);
int GetOpenCount(AutoLock::Type locktype = AutoLock::NONE) const;
int Dup(int fd) {
AutoLock lock(&fdent_lock);
return DupWithLock(fd);
}
int DupWithLock(int fd) REQUIRES(FdEntity::fdent_lock);
int OpenPseudoFd(int flags = O_RDONLY);
int GetOpenCount() const {
AutoLock lock(&fdent_lock);
return GetOpenCountHasLock();
}
int GetOpenCountHasLock() const REQUIRES(FdEntity::fdent_lock);
// TODO: should thsi require a lock?
const std::string& GetPath() const { return path; }
bool RenamePath(const std::string& newpath, std::string& fentmapkey);
int GetPhysicalFd() const { return physical_fd; }
bool IsModified() const;
bool MergeOrgMeta(headers_t& updatemeta);
int UploadPending(int fd, AutoLock::Type type);
int UploadPending(int fd) {
AutoLock auto_lock(&fdent_lock);
return UploadPendingHasLock(fd);
}
int UploadPendingHasLock(int fd) REQUIRES(FdEntity::fdent_lock);
bool GetStats(struct stat& st, AutoLock::Type locktype = AutoLock::NONE) const;
int SetCtime(struct timespec time, AutoLock::Type locktype = AutoLock::NONE);
int SetAtime(struct timespec time, AutoLock::Type locktype = AutoLock::NONE);
int SetMCtime(struct timespec mtime, struct timespec ctime, AutoLock::Type locktype = AutoLock::NONE);
bool GetStats(struct stat& st) const {
AutoLock lock(&fdent_lock);
return GetStatsHasLock(st);
}
bool GetStatsHasLock(struct stat& st) const REQUIRES(FdEntity::fdent_lock);
int SetCtime(struct timespec time) {
AutoLock lock(&fdent_lock);
return SetCtimeHasLock(time);
}
int SetCtimeHasLock(struct timespec time) REQUIRES(FdEntity::fdent_lock);
int SetAtime(struct timespec time) {
AutoLock lock(&fdent_lock);
return SetAtimeHasLock(time);
}
int SetAtimeHasLock(struct timespec time) REQUIRES(FdEntity::fdent_lock);
int SetMCtime(struct timespec mtime, struct timespec ctime) {
AutoLock lock(&fdent_lock);
return SetMCtimeHasLock(mtime, ctime);
}
int SetMCtimeHasLock(struct timespec mtime, struct timespec ctime) REQUIRES(FdEntity::fdent_lock);
bool UpdateCtime();
bool UpdateAtime();
bool UpdateMtime(bool clear_holding_mtime = false);
bool UpdateMCtime();
bool SetHoldingMtime(struct timespec mtime, AutoLock::Type locktype = AutoLock::NONE);
bool ClearHoldingMtime(AutoLock::Type locktype = AutoLock::NONE);
bool SetHoldingMtime(struct timespec mtime);
bool ClearHoldingMtime() REQUIRES(FdEntity::fdent_lock);
bool GetSize(off_t& size) const;
bool GetXattr(std::string& xattr) const;
bool SetXattr(const std::string& xattr);
bool SetMode(mode_t mode);
bool SetUId(uid_t uid);
bool SetGId(gid_t gid);
bool SetMode(mode_t mode) {
AutoLock lock(&fdent_lock);
return SetModeHasLock(mode);
}
bool SetModeHasLock(mode_t mode) REQUIRES(FdEntity::fdent_lock);
bool SetUId(uid_t uid) {
AutoLock lock(&fdent_lock);
return SetUIdHasLock(uid);
}
bool SetUIdHasLock(uid_t uid) REQUIRES(FdEntity::fdent_lock);
bool SetGId(gid_t gid) {
AutoLock lock(&fdent_lock);
return SetGIdHasLock(gid);
}
bool SetGIdHasLock(gid_t gid) REQUIRES(FdEntity::fdent_lock);
bool SetContentType(const char* path);
int Load(off_t start, off_t size, AutoLock::Type type, bool is_modified_flag = false); // size=0 means loading to end
int Load(off_t start, off_t size, bool is_modified_flag = false) REQUIRES(FdEntity::fdent_lock, FdEntity::&fdent_data_lock); // size=0 means loading to end
off_t BytesModified();
int RowFlush(int fd, const char* tpath, AutoLock::Type type, bool force_sync = false);
int Flush(int fd, AutoLock::Type type, bool force_sync = false) { return RowFlush(fd, nullptr, type, force_sync); }
int RowFlush(int fd, const char* tpath, bool force_sync = false) {
AutoLock lock(&fdent_lock);
return RowFlushHasLock(fd, tpath, force_sync);
}
int RowFlushHasLock(int fd, const char* tpath, bool force_sync = false) REQUIRES(FdEntity::fdent_lock);
int Flush(int fd, bool force_sync = false) {
AutoLock lock(&fdent_lock);
return FlushHasLock(fd, force_sync);
}
int FlushHasLock(int fd, bool force_sync = false) REQUIRES(FdEntity::fdent_lock) { return RowFlushHasLock(fd, nullptr, force_sync); }
ssize_t Read(int fd, char* bytes, off_t start, size_t size, bool force_load = false);
ssize_t Write(int fd, const char* bytes, off_t start, size_t size);

View File

@ -63,7 +63,7 @@ void* PseudoFdInfo::MultipartUploadThreadWorker(void* arg)
if(0 != (result = pthparam->ppseudofdinfo->last_result)){
S3FS_PRN_DBG("Already occurred error, thus this thread worker is exiting.");
if(!pthparam->ppseudofdinfo->CompleteInstruction(result, AutoLock::ALREADY_LOCKED)){ // result will be overwritten with the same value.
if(!pthparam->ppseudofdinfo->CompleteInstruction(result)){ // result will be overwritten with the same value.
result = -EIO;
}
return reinterpret_cast<void*>(result);
@ -76,7 +76,8 @@ void* PseudoFdInfo::MultipartUploadThreadWorker(void* arg)
S3FS_PRN_ERR("failed creating s3fs curl object for uploading [path=%s][start=%lld][size=%lld][part=%d]", pthparam->path.c_str(), static_cast<long long>(pthparam->start), static_cast<long long>(pthparam->size), pthparam->part_num);
// set result for exiting
if(!pthparam->ppseudofdinfo->CompleteInstruction(result, AutoLock::NONE)){
AutoLock auto_lock(&pthparam->ppseudofdinfo->upload_list_lock);
if(!pthparam->ppseudofdinfo->CompleteInstruction(result)){
result = -EIO;
}
return reinterpret_cast<void*>(result);
@ -95,7 +96,8 @@ void* PseudoFdInfo::MultipartUploadThreadWorker(void* arg)
s3fscurl->DestroyCurlHandle(true, false);
// set result
if(!pthparam->ppseudofdinfo->CompleteInstruction(result, AutoLock::NONE)){
AutoLock auto_lock(&pthparam->ppseudofdinfo->upload_list_lock);
if(!pthparam->ppseudofdinfo->CompleteInstruction(result)){
S3FS_PRN_WARN("This thread worker is about to end, so it doesn't return an EIO here and runs to the end.");
}
@ -143,9 +145,17 @@ bool PseudoFdInfo::Clear()
{
// cppcheck-suppress unmatchedSuppression
// cppcheck-suppress knownConditionTrueFalse
if(!CancelAllThreads() || !ResetUploadInfo(AutoLock::NONE)){
if(!CancelAllThreads()){
return false;
}
{
AutoLock auto_lock(&upload_list_lock);
// cppcheck-suppress unmatchedSuppression
// cppcheck-suppress knownConditionTrueFalse
if(!ResetUploadInfo()){
return false;
}
}
CloseUploadFd();
if(-1 != pseudo_fd){
@ -166,10 +176,8 @@ void PseudoFdInfo::CloseUploadFd()
}
}
bool PseudoFdInfo::OpenUploadFd(AutoLock::Type type)
bool PseudoFdInfo::OpenUploadFd()
{
AutoLock auto_lock(&upload_list_lock, type);
if(-1 != upload_fd){
// already initialized
return true;
@ -244,13 +252,13 @@ bool PseudoFdInfo::ClearUploadInfo(bool is_cancel_mp)
return false;
}
}
return ResetUploadInfo(AutoLock::NONE);
AutoLock auto_lock(&upload_list_lock);
return ResetUploadInfo();
}
bool PseudoFdInfo::ResetUploadInfo(AutoLock::Type type)
bool PseudoFdInfo::ResetUploadInfo()
{
AutoLock auto_lock(&upload_list_lock, type);
upload_id.clear();
upload_list.clear();
instruct_count = 0;
@ -260,13 +268,8 @@ bool PseudoFdInfo::ResetUploadInfo(AutoLock::Type type)
return true;
}
bool PseudoFdInfo::RowInitialUploadInfo(const std::string& id, bool is_cancel_mp, AutoLock::Type type)
bool PseudoFdInfo::RowInitialUploadInfo(const std::string& id, bool is_cancel_mp)
{
if(is_cancel_mp && AutoLock::ALREADY_LOCKED == type){
S3FS_PRN_ERR("Internal Error: Could not call this with type=AutoLock::ALREADY_LOCKED and is_cancel_mp=true");
return false;
}
if(is_cancel_mp){
// cppcheck-suppress unmatchedSuppression
// cppcheck-suppress knownConditionTrueFalse
@ -274,22 +277,21 @@ bool PseudoFdInfo::RowInitialUploadInfo(const std::string& id, bool is_cancel_mp
return false;
}
}else{
AutoLock auto_lock(&upload_list_lock);
// cppcheck-suppress unmatchedSuppression
// cppcheck-suppress knownConditionTrueFalse
if(!ResetUploadInfo(type)){
if(!ResetUploadInfo()){
return false;
}
}
AutoLock auto_lock(&upload_list_lock, type);
AutoLock auto_lock(&upload_list_lock);
upload_id = id;
return true;
}
bool PseudoFdInfo::CompleteInstruction(int result, AutoLock::Type type)
bool PseudoFdInfo::CompleteInstruction(int result)
{
AutoLock auto_lock(&upload_list_lock, type);
if(0 != result){
last_result = result;
}
@ -382,7 +384,7 @@ static bool filepart_partnum_compare(const filepart& src1, const filepart& src2)
return src1.get_part_number() < src2.get_part_number();
}
bool PseudoFdInfo::InsertUploadPart(off_t start, off_t size, int part_num, bool is_copy, etagpair** ppetag, AutoLock::Type type)
bool PseudoFdInfo::InsertUploadPart(off_t start, off_t size, int part_num, bool is_copy, etagpair** ppetag)
{
//S3FS_PRN_DBG("[start=%lld][size=%lld][part_num=%d][is_copy=%s]", static_cast<long long int>(start), static_cast<long long int>(size), part_num, (is_copy ? "true" : "false"));
@ -395,8 +397,6 @@ bool PseudoFdInfo::InsertUploadPart(off_t start, off_t size, int part_num, bool
return false;
}
AutoLock auto_lock(&upload_list_lock, type);
// insert new part
etagpair* petag_entity = etag_entities.add(etagpair(nullptr, part_num));
upload_list.emplace_back(false, physical_fd, start, size, is_copy, petag_entity);
@ -414,24 +414,22 @@ bool PseudoFdInfo::InsertUploadPart(off_t start, off_t size, int part_num, bool
// This method only launches the upload thread.
// Check the maximum number of threads before calling.
//
bool PseudoFdInfo::ParallelMultipartUpload(const char* path, const mp_part_list_t& mplist, bool is_copy, AutoLock::Type type)
bool PseudoFdInfo::ParallelMultipartUpload(const char* path, const mp_part_list_t& mplist, bool is_copy)
{
//S3FS_PRN_DBG("[path=%s][mplist(%zu)]", SAFESTRPTR(path), mplist.size());
AutoLock auto_lock(&upload_list_lock, type);
if(mplist.empty()){
// nothing to do
return true;
}
if(!OpenUploadFd(AutoLock::ALREADY_LOCKED)){
if(!OpenUploadFd()){
return false;
}
for(mp_part_list_t::const_iterator iter = mplist.begin(); iter != mplist.end(); ++iter){
// Insert upload part
etagpair* petag = nullptr;
if(!InsertUploadPart(iter->start, iter->size, iter->part_num, is_copy, &petag, AutoLock::ALREADY_LOCKED)){
if(!InsertUploadPart(iter->start, iter->size, iter->part_num, is_copy, &petag)){
S3FS_PRN_ERR("Failed to insert insert upload part(path=%s, start=%lld, size=%lld, part=%d, copy=%s) to mplist", SAFESTRPTR(path), static_cast<long long int>(iter->start), static_cast<long long int>(iter->size), iter->part_num, (is_copy ? "true" : "false"));
return false;
}
@ -471,13 +469,16 @@ bool PseudoFdInfo::ParallelMultipartUploadAll(const char* path, const mp_part_li
result = 0;
if(!OpenUploadFd(AutoLock::NONE)){
return false;
}
{
AutoLock auto_lock(&upload_list_lock);
if(!OpenUploadFd()){
return false;
}
if(!ParallelMultipartUpload(path, to_upload_list, false, AutoLock::NONE) || !ParallelMultipartUpload(path, copy_list, true, AutoLock::NONE)){
S3FS_PRN_ERR("Failed setup instruction for uploading(path=%s, to_upload_list=%zu, copy_list=%zu).", SAFESTRPTR(path), to_upload_list.size(), copy_list.size());
return false;
if(!ParallelMultipartUpload(path, to_upload_list, false) || !ParallelMultipartUpload(path, copy_list, true)){
S3FS_PRN_ERR("Failed setup instruction for uploading(path=%s, to_upload_list=%zu, copy_list=%zu).", SAFESTRPTR(path), to_upload_list.size(), copy_list.size());
return false;
}
}
// Wait for all thread exiting
@ -511,7 +512,6 @@ ssize_t PseudoFdInfo::UploadBoundaryLastUntreatedArea(const char* path, headers_
S3FS_PRN_ERR("pseudo_fd(%d) to physical_fd(%d) for path(%s) is not opened or not writable, or pfdent is nullptr.", pseudo_fd, physical_fd, path);
return -EBADF;
}
AutoLock auto_lock(&upload_list_lock);
//
// Get last update untreated area
@ -578,7 +578,7 @@ ssize_t PseudoFdInfo::UploadBoundaryLastUntreatedArea(const char* path, headers_
S3FS_PRN_ERR("failed to setup multipart upload(create upload id) by errno(%d)", result);
return result;
}
if(!RowInitialUploadInfo(tmp_upload_id, false/* not need to cancel */, AutoLock::ALREADY_LOCKED)){
if(!RowInitialUploadInfo(tmp_upload_id, false/* not need to cancel */)){
S3FS_PRN_ERR("failed to setup multipart upload(set upload id to object)");
return result;
}
@ -598,7 +598,7 @@ ssize_t PseudoFdInfo::UploadBoundaryLastUntreatedArea(const char* path, headers_
//
// Upload Multipart parts
//
if(!ParallelMultipartUpload(path, to_upload_list, false, AutoLock::ALREADY_LOCKED)){
if(!ParallelMultipartUpload(path, to_upload_list, false)){
S3FS_PRN_ERR("Failed to upload multipart parts.");
return -EIO;
}

View File

@ -79,12 +79,12 @@ class PseudoFdInfo
bool Clear();
void CloseUploadFd();
bool OpenUploadFd(AutoLock::Type type = AutoLock::NONE);
bool ResetUploadInfo(AutoLock::Type type);
bool RowInitialUploadInfo(const std::string& id, bool is_cancel_mp, AutoLock::Type type);
bool CompleteInstruction(int result, AutoLock::Type type = AutoLock::NONE);
bool ParallelMultipartUpload(const char* path, const mp_part_list_t& mplist, bool is_copy, AutoLock::Type type = AutoLock::NONE);
bool InsertUploadPart(off_t start, off_t size, int part_num, bool is_copy, etagpair** ppetag, AutoLock::Type type = AutoLock::NONE);
bool OpenUploadFd() REQUIRES(PseudoFdInfo::upload_list_lock);
bool ResetUploadInfo() REQUIRES(PseudoFdInfo::upload_list_lock);
bool RowInitialUploadInfo(const std::string& id, bool is_cancel_mp);
bool CompleteInstruction(int result) REQUIRES(S3fsCurl::curl_handles_lock);
bool ParallelMultipartUpload(const char* path, const mp_part_list_t& mplist, bool is_copy) REQUIRES(PseudoFdInfo::upload_list_lock);
bool InsertUploadPart(off_t start, off_t size, int part_num, bool is_copy, etagpair** ppetag) REQUIRES(PseudoFdInfo::upload_list_lock);
bool CancelAllThreads();
bool ExtractUploadPartsFromUntreatedArea(const off_t& untreated_start, const off_t& untreated_size, mp_part_list_t& to_upload_list, filepart_list_t& cancel_upload_list, off_t max_mp_size);
@ -104,7 +104,7 @@ class PseudoFdInfo
bool Set(int fd, int open_flags);
bool ClearUploadInfo(bool is_cancel_mp = false);
bool InitialUploadInfo(const std::string& id){ return RowInitialUploadInfo(id, true, AutoLock::NONE); }
bool InitialUploadInfo(const std::string& id){ return RowInitialUploadInfo(id, true); }
bool IsUploading() const { return !upload_id.empty(); }
bool GetUploadId(std::string& id) const;

View File

@ -940,7 +940,7 @@ static int get_local_fent(AutoFdEntity& autoent, FdEntity **entity, const char*
}
bool force_tmpfile = S_ISREG(stobj.st_mode) ? false : true;
if(nullptr == (ent = autoent.Open(path, &meta, stobj.st_size, st_mctime, flags, force_tmpfile, true, false, AutoLock::NONE))){
if(nullptr == (ent = autoent.Open(path, &meta, stobj.st_size, st_mctime, flags, force_tmpfile, true, false))){
S3FS_PRN_ERR("Could not open file. errno(%d)", errno);
return -EIO;
}
@ -1203,7 +1203,7 @@ static int s3fs_create(const char* _path, mode_t mode, struct fuse_file_info* fi
AutoFdEntity autoent;
FdEntity* ent;
int error = 0;
if(nullptr == (ent = autoent.Open(path, &meta, 0, S3FS_OMIT_TS, fi->flags, false, true, false, AutoLock::NONE, &error))){
if(nullptr == (ent = autoent.Open(path, &meta, 0, S3FS_OMIT_TS, fi->flags, false, true, false, &error))){
StatCache::getStatCacheData()->DelStat(path);
return error;
}
@ -1440,7 +1440,7 @@ static int s3fs_symlink(const char* _from, const char* _to)
{ // scope for AutoFdEntity
AutoFdEntity autoent;
FdEntity* ent;
if(nullptr == (ent = autoent.Open(to, &headers, 0, S3FS_OMIT_TS, O_RDWR, true, true, false, AutoLock::NONE))){
if(nullptr == (ent = autoent.Open(to, &headers, 0, S3FS_OMIT_TS, O_RDWR, true, true, false))){
S3FS_PRN_ERR("could not open tmpfile(errno=%d)", errno);
return -errno;
}
@ -1458,7 +1458,7 @@ static int s3fs_symlink(const char* _from, const char* _to)
}
}
// upload
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), AutoLock::NONE, true))){
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), true))){
S3FS_PRN_WARN("could not upload tmpfile(result=%d)", result);
}
}
@ -1553,7 +1553,7 @@ static int rename_object(const char* from, const char* to, bool update_ctime)
// This does not affect the rename process, but the cache information in
// the "modified" state remains, making it impossible to read the file correctly.
//
ent = autoent.Open(from, &meta, buf.st_size, mtime, O_RDONLY, false, true, false, AutoLock::NONE);
ent = autoent.Open(from, &meta, buf.st_size, mtime, O_RDONLY, false, true, false);
}
if(ent){
ent->SetMCtime(mtime, ctime);
@ -1616,7 +1616,7 @@ static int rename_object_nocopy(const char* from, const char* to, bool update_ct
}
// upload
if(0 != (result = ent->RowFlush(autoent.GetPseudoFd(), to, AutoLock::NONE, true))){
if(0 != (result = ent->RowFlush(autoent.GetPseudoFd(), to, true))){
S3FS_PRN_ERR("could not upload file(%s): result=%d", to, result);
return result;
}
@ -1870,7 +1870,7 @@ static int s3fs_rename(const char* _from, const char* _to)
AutoFdEntity autoent;
FdEntity* ent;
if(nullptr != (ent = autoent.OpenExistFdEntity(from, O_RDWR))){
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), AutoLock::NONE, true))){
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), true))){
S3FS_PRN_ERR("could not upload file(%s): result=%d", to, result);
return result;
}
@ -2111,7 +2111,7 @@ static int s3fs_chmod_nocopy(const char* _path, mode_t mode)
ent->SetMode(mode);
// upload
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), AutoLock::NONE, true))){
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), true))){
S3FS_PRN_ERR("could not upload file(%s): result=%d", strpath.c_str(), result);
return result;
}
@ -2334,7 +2334,7 @@ static int s3fs_chown_nocopy(const char* _path, uid_t uid, gid_t gid)
ent->SetGId(gid);
// upload
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), AutoLock::NONE, true))){
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), true))){
S3FS_PRN_ERR("could not upload file(%s): result=%d", strpath.c_str(), result);
return result;
}
@ -2699,7 +2699,7 @@ static int s3fs_utimens_nocopy(const char* _path, const struct timespec ts[2])
}
// upload
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), AutoLock::NONE, true))){
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), true))){
S3FS_PRN_ERR("could not upload file(%s): result=%d", strpath.c_str(), result);
return result;
}
@ -2761,7 +2761,7 @@ static int s3fs_truncate(const char* _path, off_t size)
ignore_modify = true;
}
if(nullptr == (ent = autoent.Open(path, &meta, size, S3FS_OMIT_TS, O_RDWR, false, true, ignore_modify, AutoLock::NONE))){
if(nullptr == (ent = autoent.Open(path, &meta, size, S3FS_OMIT_TS, O_RDWR, false, true, ignore_modify))){
S3FS_PRN_ERR("could not open file(%s): errno=%d", path, errno);
return -EIO;
}
@ -2773,7 +2773,7 @@ static int s3fs_truncate(const char* _path, off_t size)
// The cause is unknown now, but it can be avoided by flushing the file.
//
if(0 == size){
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), AutoLock::NONE, true))){
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), true))){
S3FS_PRN_ERR("could not upload file(%s): result=%d", path, result);
return result;
}
@ -2796,11 +2796,11 @@ static int s3fs_truncate(const char* _path, off_t size)
meta["x-amz-meta-uid"] = std::to_string(pcxt->uid);
meta["x-amz-meta-gid"] = std::to_string(pcxt->gid);
if(nullptr == (ent = autoent.Open(path, &meta, size, S3FS_OMIT_TS, O_RDWR, true, true, false, AutoLock::NONE))){
if(nullptr == (ent = autoent.Open(path, &meta, size, S3FS_OMIT_TS, O_RDWR, true, true, false))){
S3FS_PRN_ERR("could not open file(%s): errno=%d", path, errno);
return -EIO;
}
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), AutoLock::NONE, true))){
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), true))){
S3FS_PRN_ERR("could not upload file(%s): result=%d", path, result);
return result;
}
@ -2883,7 +2883,7 @@ static int s3fs_open(const char* _path, struct fuse_file_info* fi)
struct timespec st_mctime;
set_stat_to_timespec(st, stat_time_type::MTIME, st_mctime);
if(nullptr == (ent = autoent.Open(path, &meta, st.st_size, st_mctime, fi->flags, false, true, false, AutoLock::NONE))){
if(nullptr == (ent = autoent.Open(path, &meta, st.st_size, st_mctime, fi->flags, false, true, false))){
StatCache::getStatCacheData()->DelStat(path);
return -EIO;
}
@ -2891,9 +2891,10 @@ static int s3fs_open(const char* _path, struct fuse_file_info* fi)
if (needs_flush){
struct timespec ts;
s3fs_realtime(ts);
ent->SetMCtime(ts, ts);
if(0 != (result = ent->RowFlush(autoent.GetPseudoFd(), path, AutoLock::NONE, true))){
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;
@ -2954,7 +2955,7 @@ static int s3fs_write(const char* _path, const char* buf, size_t size, off_t off
if(max_dirty_data != -1 && ent->BytesModified() >= max_dirty_data){
int flushres;
if(0 != (flushres = ent->RowFlush(static_cast<int>(fi->fh), path, AutoLock::NONE, true))){
if(0 != (flushres = ent->RowFlush(static_cast<int>(fi->fh), path, true))){
S3FS_PRN_ERR("could not upload file(%s): result=%d", path, flushres);
StatCache::getStatCacheData()->DelStat(path);
return flushres;
@ -3023,7 +3024,7 @@ static int s3fs_flush(const char* _path, struct fuse_file_info* fi)
ent->UpdateMtime(true); // clear the flag not to update mtime.
ent->UpdateCtime();
result = ent->Flush(static_cast<int>(fi->fh), AutoLock::NONE, false);
result = ent->Flush(static_cast<int>(fi->fh), false);
StatCache::getStatCacheData()->DelStat(path);
if(is_new_file){
@ -3058,7 +3059,7 @@ static int s3fs_fsync(const char* _path, int datasync, struct fuse_file_info* fi
ent->UpdateMtime();
ent->UpdateCtime();
}
result = ent->Flush(static_cast<int>(fi->fh), AutoLock::NONE, false);
result = ent->Flush(static_cast<int>(fi->fh), false);
if(0 != datasync){
// [NOTE]
@ -3112,7 +3113,7 @@ static int s3fs_release(const char* _path, struct fuse_file_info* fi)
//
int result;
if(ent->IsModified()){
if(0 != (result = ent->Flush(static_cast<int>(fi->fh), AutoLock::NONE, false))){
if(0 != (result = ent->Flush(static_cast<int>(fi->fh), false))){
S3FS_PRN_ERR("failed to upload file contentsfor pseudo_fd(%llu) / path(%s) by result(%d)", (unsigned long long)(fi->fh), path, result);
return result;
}
@ -3135,7 +3136,7 @@ static int s3fs_release(const char* _path, struct fuse_file_info* fi)
bool is_new_file = ent->IsDirtyNewFile();
if(0 != (result = ent->UploadPending(static_cast<int>(fi->fh), AutoLock::NONE))){
if(0 != (result = ent->UploadPending(static_cast<int>(fi->fh)))){
S3FS_PRN_ERR("could not upload pending data(meta, etc) for pseudo_fd(%llu) / path(%s)", (unsigned long long)(fi->fh), path);
return result;
}

View File

@ -250,10 +250,8 @@ bool S3fsCred::SetIAMRoleMetadataType(bool flag)
return old;
}
bool S3fsCred::SetAccessKey(const char* AccessKeyId, const char* SecretAccessKey, AutoLock::Type type)
bool S3fsCred::SetAccessKey(const char* AccessKeyId, const char* SecretAccessKey)
{
AutoLock auto_lock(&token_lock, type);
if((!is_ibm_iam_auth && (!AccessKeyId || '\0' == AccessKeyId[0])) || !SecretAccessKey || '\0' == SecretAccessKey[0]){
return false;
}
@ -263,10 +261,8 @@ bool S3fsCred::SetAccessKey(const char* AccessKeyId, const char* SecretAccessKey
return true;
}
bool S3fsCred::SetAccessKeyWithSessionToken(const char* AccessKeyId, const char* SecretAccessKey, const char * SessionToken, AutoLock::Type type)
bool S3fsCred::SetAccessKeyWithSessionToken(const char* AccessKeyId, const char* SecretAccessKey, const char * SessionToken)
{
AutoLock auto_lock(&token_lock, type);
bool access_key_is_empty = !AccessKeyId || '\0' == AccessKeyId[0];
bool secret_access_key_is_empty = !SecretAccessKey || '\0' == SecretAccessKey[0];
bool session_token_is_empty = !SessionToken || '\0' == SessionToken[0];
@ -282,11 +278,9 @@ bool S3fsCred::SetAccessKeyWithSessionToken(const char* AccessKeyId, const char*
return true;
}
bool S3fsCred::IsSetAccessKeys(AutoLock::Type type) const
bool S3fsCred::IsSetAccessKeys() const
{
AutoLock auto_lock(&token_lock, type);
return IsSetIAMRole(AutoLock::ALREADY_LOCKED) || ((!AWSAccessKeyId.empty() || is_ibm_iam_auth) && !AWSSecretAccessKey.empty());
return IsSetIAMRole() || ((!AWSAccessKeyId.empty() || is_ibm_iam_auth) && !AWSSecretAccessKey.empty());
}
bool S3fsCred::SetIsECS(bool flag)
@ -310,25 +304,19 @@ bool S3fsCred::SetIsIBMIAMAuth(bool flag)
return old;
}
bool S3fsCred::SetIAMRole(const char* role, AutoLock::Type type)
bool S3fsCred::SetIAMRole(const char* role)
{
AutoLock auto_lock(&token_lock, type);
IAM_role = role ? role : "";
return true;
}
std::string S3fsCred::GetIAMRole(AutoLock::Type type) const
const std::string& S3fsCred::GetIAMRole() const
{
AutoLock auto_lock(&token_lock, type);
return IAM_role;
}
bool S3fsCred::IsSetIAMRole(AutoLock::Type type) const
bool S3fsCred::IsSetIAMRole() const
{
AutoLock auto_lock(&token_lock, type);
return !IAM_role.empty();
}
@ -360,15 +348,15 @@ std::string S3fsCred::SetIAMExpiryField(const char* expiry_field)
return old;
}
bool S3fsCred::GetIAMCredentialsURL(std::string& url, bool check_iam_role, AutoLock::Type type)
bool S3fsCred::GetIAMCredentialsURL(std::string& url, bool check_iam_role)
{
// check
if(check_iam_role && !is_ecs && !IsIBMIAMAuth()){
if(!IsSetIAMRole(type)) {
if(!IsSetIAMRole()) {
S3FS_PRN_ERR("IAM role name is empty.");
return false;
}
S3FS_PRN_INFO3("[IAM role=%s]", GetIAMRole(type).c_str());
S3FS_PRN_INFO3("[IAM role=%s]", GetIAMRole().c_str());
}
if(is_ecs){
@ -387,9 +375,7 @@ bool S3fsCred::GetIAMCredentialsURL(std::string& url, bool check_iam_role, AutoL
// To avoid deadlocking, do not manipulate the S3fsCred object
// in the S3fsCurl::GetIAMv2ApiToken method (when retrying).
//
AutoLock auto_lock(&token_lock, type); // Lock for IAM_api_version, IAMv2_api_token
if(GetIMDSVersion(AutoLock::ALREADY_LOCKED) > 1){
if(GetIMDSVersion() > 1){
S3fsCurl s3fscurl;
std::string token;
int result = s3fscurl.GetIAMv2ApiToken(S3fsCred::IAMv2_token_url, S3fsCred::IAMv2_token_ttl, S3fsCred::IAMv2_token_ttl_hdr, token);
@ -398,7 +384,7 @@ bool S3fsCred::GetIAMCredentialsURL(std::string& url, bool check_iam_role, AutoL
// then it's highly likely we're running in an environment
// that doesn't support the AWS IMDSv2 API, so we'll skip
// the token retrieval in the future.
SetIMDSVersion(1, AutoLock::ALREADY_LOCKED);
SetIMDSVersion(1);
}else if(result != 0){
// If we get an unexpected error when retrieving the API
@ -409,13 +395,13 @@ bool S3fsCred::GetIAMCredentialsURL(std::string& url, bool check_iam_role, AutoL
}else{
// Set token
if(!SetIAMv2APIToken(token, AutoLock::ALREADY_LOCKED)){
if(!SetIAMv2APIToken(token)){
S3FS_PRN_ERR("Error storing IMDSv2 API token(%s).", token.c_str());
}
}
}
if(check_iam_role){
url = IAM_cred_url + GetIAMRole(AutoLock::ALREADY_LOCKED);
url = IAM_cred_url + GetIAMRole();
}else{
url = IAM_cred_url;
}
@ -423,28 +409,22 @@ bool S3fsCred::GetIAMCredentialsURL(std::string& url, bool check_iam_role, AutoL
return true;
}
int S3fsCred::SetIMDSVersion(int version, AutoLock::Type type)
int S3fsCred::SetIMDSVersion(int version)
{
AutoLock auto_lock(&token_lock, type);
int old = IAM_api_version;
IAM_api_version = version;
return old;
}
int S3fsCred::GetIMDSVersion(AutoLock::Type type) const
int S3fsCred::GetIMDSVersion() const
{
AutoLock auto_lock(&token_lock, type);
return IAM_api_version;
}
bool S3fsCred::SetIAMv2APIToken(const std::string& token, AutoLock::Type type)
bool S3fsCred::SetIAMv2APIToken(const std::string& token)
{
S3FS_PRN_INFO3("Setting AWS IMDSv2 API token to %s", token.c_str());
AutoLock auto_lock(&token_lock, type);
if(token.empty()){
return false;
}
@ -452,10 +432,8 @@ bool S3fsCred::SetIAMv2APIToken(const std::string& token, AutoLock::Type type)
return true;
}
std::string S3fsCred::GetIAMv2APIToken(AutoLock::Type type) const
const std::string& S3fsCred::GetIAMv2APIToken() const
{
AutoLock auto_lock(&token_lock, type);
return IAMv2_api_token;
}
@ -467,21 +445,19 @@ std::string S3fsCred::GetIAMv2APIToken(AutoLock::Type type) const
// retry logic.
// Be careful not to deadlock whenever you change this logic.
//
bool S3fsCred::LoadIAMCredentials(AutoLock::Type type)
bool S3fsCred::LoadIAMCredentials()
{
// url(check iam role)
std::string url;
AutoLock auto_lock(&token_lock, type);
if(!GetIAMCredentialsURL(url, true, AutoLock::ALREADY_LOCKED)){
if(!GetIAMCredentialsURL(url, true)){
return false;
}
const char* iam_v2_token = nullptr;
std::string str_iam_v2_token;
if(GetIMDSVersion(AutoLock::ALREADY_LOCKED) > 1){
str_iam_v2_token = GetIAMv2APIToken(AutoLock::ALREADY_LOCKED);
if(GetIMDSVersion() > 1){
str_iam_v2_token = GetIAMv2APIToken();
iam_v2_token = str_iam_v2_token.c_str();
}
@ -498,7 +474,7 @@ bool S3fsCred::LoadIAMCredentials(AutoLock::Type type)
return false;
}
if(!SetIAMCredentials(response.c_str(), AutoLock::ALREADY_LOCKED)){
if(!SetIAMCredentials(response.c_str())){
S3FS_PRN_ERR("Something error occurred, could not set IAM role name.");
return false;
}
@ -516,14 +492,14 @@ bool S3fsCred::LoadIAMRoleFromMetaData()
// url(not check iam role)
std::string url;
if(!GetIAMCredentialsURL(url, false, AutoLock::ALREADY_LOCKED)){
if(!GetIAMCredentialsURL(url, false)){
return false;
}
const char* iam_v2_token = nullptr;
std::string str_iam_v2_token;
if(GetIMDSVersion(AutoLock::ALREADY_LOCKED) > 1){
str_iam_v2_token = GetIAMv2APIToken(AutoLock::ALREADY_LOCKED);
if(GetIMDSVersion() > 1){
str_iam_v2_token = GetIAMv2APIToken();
iam_v2_token = str_iam_v2_token.c_str();
}
@ -533,16 +509,16 @@ bool S3fsCred::LoadIAMRoleFromMetaData()
return false;
}
if(!SetIAMRoleFromMetaData(token.c_str(), AutoLock::ALREADY_LOCKED)){
if(!SetIAMRoleFromMetaData(token.c_str())){
S3FS_PRN_ERR("Something error occurred, could not set IAM role name.");
return false;
}
S3FS_PRN_INFO("loaded IAM role name = %s", GetIAMRole(AutoLock::ALREADY_LOCKED).c_str());
S3FS_PRN_INFO("loaded IAM role name = %s", GetIAMRole().c_str());
}
return true;
}
bool S3fsCred::SetIAMCredentials(const char* response, AutoLock::Type type)
bool S3fsCred::SetIAMCredentials(const char* response)
{
S3FS_PRN_INFO3("IAM credential response = \"%s\"", response);
@ -556,8 +532,6 @@ bool S3fsCred::SetIAMCredentials(const char* response, AutoLock::Type type)
return false;
}
AutoLock auto_lock(&token_lock, type);
AWSAccessToken = keyval[IAM_token_field];
if(is_ibm_iam_auth){
@ -574,7 +548,7 @@ bool S3fsCred::SetIAMCredentials(const char* response, AutoLock::Type type)
return true;
}
bool S3fsCred::SetIAMRoleFromMetaData(const char* response, AutoLock::Type type)
bool S3fsCred::SetIAMRoleFromMetaData(const char* response)
{
S3FS_PRN_INFO3("IAM role name response = \"%s\"", response ? response : "(null)");
@ -583,7 +557,7 @@ bool S3fsCred::SetIAMRoleFromMetaData(const char* response, AutoLock::Type type)
return false;
}
SetIAMRole(rolename.c_str(), type);
SetIAMRole(rolename.c_str());
return true;
}
@ -785,7 +759,7 @@ bool S3fsCred::ParseS3fsPasswdFile(bucketkvmap_t& resmap)
//
// only one default key pair is allowed, but not required
//
bool S3fsCred::ReadS3fsPasswdFile(AutoLock::Type type)
bool S3fsCred::ReadS3fsPasswdFile()
{
bucketkvmap_t bucketmap;
kvmap_t keyval;
@ -817,7 +791,7 @@ bool S3fsCred::ReadS3fsPasswdFile(AutoLock::Type type)
return false;
}else if(1 == result){
// found ascess(secret) keys
if(!SetAccessKey(access_key_id.c_str(), secret_access_key.c_str(), type)){
if(!SetAccessKey(access_key_id.c_str(), secret_access_key.c_str())){
S3FS_PRN_EXIT("failed to set access key/secret key.");
return false;
}
@ -843,7 +817,7 @@ bool S3fsCred::ReadS3fsPasswdFile(AutoLock::Type type)
return false;
}
if(!SetAccessKey(aws_accesskeyid_it->second.c_str(), aws_secretkey_it->second.c_str(), type)){
if(!SetAccessKey(aws_accesskeyid_it->second.c_str(), aws_secretkey_it->second.c_str())){
S3FS_PRN_EXIT("failed to set internal data for access key/secret key from passwd file.");
return false;
}
@ -881,7 +855,7 @@ int S3fsCred::CheckS3fsCredentialAwsFormat(const kvmap_t& kvmap, std::string& ac
//
// Read Aws Credential File
//
bool S3fsCred::ReadAwsCredentialFile(const std::string &filename, AutoLock::Type type)
bool S3fsCred::ReadAwsCredentialFile(const std::string &filename)
{
// open passwd file
std::ifstream PF(filename.c_str());
@ -938,12 +912,12 @@ bool S3fsCred::ReadAwsCredentialFile(const std::string &filename, AutoLock::Type
S3FS_PRN_EXIT("AWS session token was expected but wasn't provided in aws/credentials file for profile: %s.", aws_profile.c_str());
return false;
}
if(!SetAccessKey(accesskey.c_str(), secret.c_str(), type)){
if(!SetAccessKey(accesskey.c_str(), secret.c_str())){
S3FS_PRN_EXIT("failed to set internal data for access key/secret key from aws credential file.");
return false;
}
}else{
if(!SetAccessKeyWithSessionToken(accesskey.c_str(), secret.c_str(), session_token.c_str(), type)){
if(!SetAccessKeyWithSessionToken(accesskey.c_str(), secret.c_str(), session_token.c_str())){
S3FS_PRN_EXIT("session token is invalid.");
return false;
}
@ -981,13 +955,13 @@ bool S3fsCred::InitialS3fsCredentials()
}
// 1 - keys specified on the command line
if(IsSetAccessKeys(AutoLock::NONE)){
if(IsSetAccessKeys()){
return true;
}
// 2 - was specified on the command line
if(IsSetPasswdFile()){
if(!ReadS3fsPasswdFile(AutoLock::NONE)){
if(!ReadS3fsPasswdFile()){
return false;
}
return true;
@ -1007,7 +981,7 @@ bool S3fsCred::InitialS3fsCredentials()
S3FS_PRN_INFO2("access key from env variables");
if(AWSSESSIONTOKEN != nullptr){
S3FS_PRN_INFO2("session token is available");
if(!SetAccessKeyWithSessionToken(AWSACCESSKEYID, AWSSECRETACCESSKEY, AWSSESSIONTOKEN, AutoLock::NONE)){
if(!SetAccessKeyWithSessionToken(AWSACCESSKEYID, AWSSECRETACCESSKEY, AWSSESSIONTOKEN)){
S3FS_PRN_EXIT("session token is invalid.");
return false;
}
@ -1018,7 +992,7 @@ bool S3fsCred::InitialS3fsCredentials()
return false;
}
}
if(!SetAccessKey(AWSACCESSKEYID, AWSSECRETACCESSKEY, AutoLock::NONE)){
if(!SetAccessKey(AWSACCESSKEYID, AWSSECRETACCESSKEY)){
S3FS_PRN_EXIT("if one access key is specified, both keys need to be specified.");
return false;
}
@ -1034,7 +1008,7 @@ bool S3fsCred::InitialS3fsCredentials()
S3FS_PRN_EXIT("AWS_CREDENTIAL_FILE: \"%s\" is not readable.", passwd_file.c_str());
return false;
}
if(!ReadS3fsPasswdFile(AutoLock::NONE)){
if(!ReadS3fsPasswdFile()){
return false;
}
return true;
@ -1043,7 +1017,7 @@ bool S3fsCred::InitialS3fsCredentials()
// 3b - check ${HOME}/.aws/credentials
std::string aws_credentials = std::string(getpwuid(getuid())->pw_dir) + "/.aws/credentials";
if(ReadAwsCredentialFile(aws_credentials, AutoLock::NONE)){
if(ReadAwsCredentialFile(aws_credentials)){
return true;
}else if(aws_profile != DEFAULT_AWS_PROFILE_NAME){
S3FS_PRN_EXIT("Could not find profile: %s in file: %s", aws_profile.c_str(), aws_credentials.c_str());
@ -1056,14 +1030,14 @@ bool S3fsCred::InitialS3fsCredentials()
passwd_file = HOME;
passwd_file += "/.passwd-s3fs";
if(IsReadableS3fsPasswdFile()){
if(!ReadS3fsPasswdFile(AutoLock::NONE)){
if(!ReadS3fsPasswdFile()){
return false;
}
// It is possible that the user's file was there but
// contained no key pairs i.e. commented out
// in that case, go look in the final location
if(IsSetAccessKeys(AutoLock::NONE)){
if(IsSetAccessKeys()){
return true;
}
}
@ -1072,7 +1046,7 @@ bool S3fsCred::InitialS3fsCredentials()
// 5 - from the system default location
passwd_file = "/etc/passwd-s3fs";
if(IsReadableS3fsPasswdFile()){
if(!ReadS3fsPasswdFile(AutoLock::NONE)){
if(!ReadS3fsPasswdFile()){
return false;
}
return true;
@ -1144,18 +1118,18 @@ bool S3fsCred::CheckIAMCredentialUpdate(std::string* access_key_id, std::string*
{
AutoLock auto_lock(&token_lock);
if(IsIBMIAMAuth() || IsSetExtCredLib() || is_ecs || IsSetIAMRole(AutoLock::ALREADY_LOCKED)){
if(IsIBMIAMAuth() || IsSetExtCredLib() || is_ecs || IsSetIAMRole()){
if(AWSAccessTokenExpire < (time(nullptr) + S3fsCred::IAM_EXPIRE_MERGIN)){
S3FS_PRN_INFO("IAM Access Token refreshing...");
// update
if(!IsSetExtCredLib()){
if(!LoadIAMCredentials(AutoLock::ALREADY_LOCKED)){
if(!LoadIAMCredentials()){
S3FS_PRN_ERR("Access Token refresh by built-in failed");
return false;
}
}else{
if(!UpdateExtCredentials(AutoLock::ALREADY_LOCKED)){
if(!UpdateExtCredentials()){
S3FS_PRN_ERR("Access Token refresh by %s(external credential library) failed", credlib.c_str());
return false;
}
@ -1172,7 +1146,7 @@ bool S3fsCred::CheckIAMCredentialUpdate(std::string* access_key_id, std::string*
*secret_access_key = AWSSecretAccessKey;
}
if(access_token){
if(IsIBMIAMAuth() || IsSetExtCredLib() || is_ecs || is_use_session_token || IsSetIAMRole(AutoLock::ALREADY_LOCKED)){
if(IsIBMIAMAuth() || IsSetExtCredLib() || is_ecs || is_use_session_token || IsSetIAMRole()){
*access_token = AWSAccessToken;
}else{
access_token->clear();
@ -1334,15 +1308,13 @@ bool S3fsCred::UnloadExtCredLib()
return true;
}
bool S3fsCred::UpdateExtCredentials(AutoLock::Type type)
bool S3fsCred::UpdateExtCredentials()
{
if(!hExtCredLib){
S3FS_PRN_CRIT("External Credential Library is not loaded, why?");
return false;
}
AutoLock auto_lock(&token_lock, type);
char* paccess_key_id = nullptr;
char* pserect_access_key = nullptr;
char* paccess_token = nullptr;
@ -1402,6 +1374,8 @@ bool S3fsCred::UpdateExtCredentials(AutoLock::Type type)
//
int S3fsCred::DetectParam(const char* arg)
{
AutoLock auto_lock(&token_lock);
if(!arg){
S3FS_PRN_EXIT("parameter arg is empty(null)");
return -1;
@ -1419,7 +1393,7 @@ int S3fsCred::DetectParam(const char* arg)
SetIAMTokenField("\"access_token\"");
SetIAMExpiryField("\"expiration\"");
SetIAMFieldCount(2);
SetIMDSVersion(1, AutoLock::NONE);
SetIMDSVersion(1);
set_builtin_cred_opts = true;
return 0;
}
@ -1446,7 +1420,7 @@ int S3fsCred::DetectParam(const char* arg)
}
if(0 == strcmp(arg, "imdsv1only")){
SetIMDSVersion(1, AutoLock::NONE);
SetIMDSVersion(1);
set_builtin_cred_opts = true;
return 0;
}
@ -1457,7 +1431,7 @@ int S3fsCred::DetectParam(const char* arg)
return -1;
}
SetIsECS(true);
SetIMDSVersion(1, AutoLock::NONE);
SetIMDSVersion(1);
SetIAMCredentialsURL("http://169.254.170.2");
SetIAMFieldCount(5);
set_builtin_cred_opts = true;
@ -1478,7 +1452,7 @@ int S3fsCred::DetectParam(const char* arg)
}else if(is_prefix(arg, "iam_role=")){
const char* role = strchr(arg, '=') + sizeof(char);
SetIAMRole(role, AutoLock::NONE);
SetIAMRole(role);
SetIAMRoleMetadataType(false);
set_builtin_cred_opts = true;
return 0;
@ -1550,6 +1524,7 @@ bool S3fsCred::CheckForbiddenBucketParams()
//
bool S3fsCred::CheckAllParams()
{
AutoLock auto_lock(&token_lock);
//
// Checking forbidden parameters for bucket
//
@ -1558,12 +1533,12 @@ bool S3fsCred::CheckAllParams()
}
// error checking of command line arguments for compatibility
if(S3fsCurl::IsPublicBucket() && IsSetAccessKeys(AutoLock::NONE)){
if(S3fsCurl::IsPublicBucket() && IsSetAccessKeys()){
S3FS_PRN_EXIT("specifying both public_bucket and the access keys options is invalid.");
return false;
}
if(IsSetPasswdFile() && IsSetAccessKeys(AutoLock::NONE)){
if(IsSetPasswdFile() && IsSetAccessKeys()){
S3FS_PRN_EXIT("specifying both passwd_file and the access keys options is invalid.");
return false;
}
@ -1572,7 +1547,7 @@ bool S3fsCred::CheckAllParams()
if(!InitialS3fsCredentials()){
return false;
}
if(!IsSetAccessKeys(AutoLock::NONE)){
if(!IsSetAccessKeys()){
S3FS_PRN_EXIT("could not establish security credentials, check documentation.");
return false;
}

View File

@ -102,24 +102,24 @@ class S3fsCred
bool SetAwsProfileName(const char* profile_name);
bool SetIAMRoleMetadataType(bool flag);
bool SetAccessKey(const char* AccessKeyId, const char* SecretAccessKey, AutoLock::Type type);
bool SetAccessKeyWithSessionToken(const char* AccessKeyId, const char* SecretAccessKey, const char * SessionToken, AutoLock::Type type);
bool IsSetAccessKeys(AutoLock::Type type) const;
bool SetAccessKey(const char* AccessKeyId, const char* SecretAccessKey) REQUIRES(S3fsCred::token_lock);
bool SetAccessKeyWithSessionToken(const char* AccessKeyId, const char* SecretAccessKey, const char * SessionToken) REQUIRES(S3fsCred::token_lock);
bool IsSetAccessKeys() const REQUIRES(S3fsCred::token_lock);
bool SetIsECS(bool flag);
bool SetIsUseSessionToken(bool flag);
bool SetIsIBMIAMAuth(bool flag);
int SetIMDSVersion(int version, AutoLock::Type type);
int GetIMDSVersion(AutoLock::Type type) const;
int SetIMDSVersion(int version) REQUIRES(S3fsCred::token_lock);
int GetIMDSVersion() const REQUIRES(S3fsCred::token_lock);
bool SetIAMv2APIToken(const std::string& token, AutoLock::Type type);
std::string GetIAMv2APIToken(AutoLock::Type type) const;
bool SetIAMv2APIToken(const std::string& token) REQUIRES(S3fsCred::token_lock);
const std::string& GetIAMv2APIToken() const REQUIRES(S3fsCred::token_lock);
bool SetIAMRole(const char* role, AutoLock::Type type);
std::string GetIAMRole(AutoLock::Type type) const;
bool IsSetIAMRole(AutoLock::Type type) const;
bool SetIAMRole(const char* role) REQUIRES(S3fsCred::token_lock);
const std::string& GetIAMRole() const REQUIRES(S3fsCred::token_lock);
bool IsSetIAMRole() const REQUIRES(S3fsCred::token_lock);
size_t SetIAMFieldCount(size_t field_count);
std::string SetIAMCredentialsURL(const char* url);
std::string SetIAMTokenField(const char* token_field);
@ -128,18 +128,18 @@ class S3fsCred
bool IsReadableS3fsPasswdFile() const;
bool CheckS3fsPasswdFilePerms();
bool ParseS3fsPasswdFile(bucketkvmap_t& resmap);
bool ReadS3fsPasswdFile(AutoLock::Type type);
bool ReadS3fsPasswdFile() REQUIRES(S3fsCred::token_lock);
static int CheckS3fsCredentialAwsFormat(const kvmap_t& kvmap, std::string& access_key_id, std::string& secret_access_key);
bool ReadAwsCredentialFile(const std::string &filename, AutoLock::Type type);
bool ReadAwsCredentialFile(const std::string &filename) REQUIRES(S3fsCred::token_lock);
bool InitialS3fsCredentials();
bool InitialS3fsCredentials() REQUIRES(S3fsCred::token_lock);
bool ParseIAMCredentialResponse(const char* response, iamcredmap_t& keyval);
bool GetIAMCredentialsURL(std::string& url, bool check_iam_role, AutoLock::Type type);
bool LoadIAMCredentials(AutoLock::Type type);
bool SetIAMCredentials(const char* response, AutoLock::Type type);
bool SetIAMRoleFromMetaData(const char* response, AutoLock::Type type);
bool GetIAMCredentialsURL(std::string& url, bool check_iam_role) REQUIRES(S3fsCred::token_lock);
bool LoadIAMCredentials() REQUIRES(S3fsCred::token_lock);
bool SetIAMCredentials(const char* response) REQUIRES(S3fsCred::token_lock);
bool SetIAMRoleFromMetaData(const char* response) REQUIRES(S3fsCred::token_lock);
bool SetExtCredLib(const char* arg);
bool IsSetExtCredLib() const;
@ -149,7 +149,7 @@ class S3fsCred
bool InitExtCredLib();
bool LoadExtCredLib();
bool UnloadExtCredLib();
bool UpdateExtCredentials(AutoLock::Type type);
bool UpdateExtCredentials() REQUIRES(S3fsCred::token_lock);
static bool CheckForbiddenBucketParams();