mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-12-22 08:48:55 +00:00
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:
parent
39c2d8b2a7
commit
2841601ad5
@ -23,6 +23,9 @@
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
// empty annotation to indicate lock requirement
|
||||
#define REQUIRES(...)
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// AutoLock Class
|
||||
//-------------------------------------------------------------------
|
||||
|
@ -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);
|
||||
|
17
src/cache.h
17
src/cache.h
@ -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);
|
||||
|
22
src/curl.cpp
22
src/curl.cpp
@ -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){
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
43
src/s3fs.cpp
43
src/s3fs.cpp
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user