mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2025-01-23 13:58:24 +00:00
Merge pull request #1404 from liuyongqing/master
fix dead lock in disk insufficient and optimize code
This commit is contained in:
commit
853be26612
@ -1032,7 +1032,6 @@ int FdEntity::NoCachePreMultipartPost()
|
|||||||
// initialize multipart upload values
|
// initialize multipart upload values
|
||||||
upload_id.erase();
|
upload_id.erase();
|
||||||
etaglist.clear();
|
etaglist.clear();
|
||||||
pending_headers.clear();
|
|
||||||
|
|
||||||
S3fsCurl s3fscurl(true);
|
S3fsCurl s3fscurl(true);
|
||||||
int result;
|
int result;
|
||||||
@ -1457,70 +1456,43 @@ bool FdEntity::MergeOrgMeta(headers_t& updatemeta)
|
|||||||
{
|
{
|
||||||
AutoLock auto_lock(&fdent_lock);
|
AutoLock auto_lock(&fdent_lock);
|
||||||
|
|
||||||
bool is_pending;
|
merge_headers(orgmeta, updatemeta, true); // overwrite all keys
|
||||||
if(upload_id.empty()){
|
// [NOTE]
|
||||||
// merge update meta
|
// this is special cases, we remove the key which has empty values.
|
||||||
headers_t mergedmeta = orgmeta;
|
for(headers_t::iterator hiter = orgmeta.begin(); hiter != orgmeta.end(); ){
|
||||||
|
if(hiter->second.empty()){
|
||||||
merge_headers(orgmeta, updatemeta, false); // overwrite existing keys only
|
orgmeta.erase(hiter++);
|
||||||
merge_headers(mergedmeta, updatemeta, true); // overwrite all keys
|
}else{
|
||||||
updatemeta = mergedmeta; // swap
|
++hiter;
|
||||||
|
}
|
||||||
is_pending = false;
|
|
||||||
}else{
|
|
||||||
// could not update meta because uploading now, then put pending.
|
|
||||||
pending_headers.push_back(updatemeta);
|
|
||||||
is_pending = true;
|
|
||||||
}
|
}
|
||||||
|
updatemeta = orgmeta;
|
||||||
|
// update ctime/mtime
|
||||||
|
time_t updatetime = get_mtime(updatemeta, false); // not overcheck
|
||||||
|
if(0 != updatetime){
|
||||||
|
SetMtime(updatetime, true);
|
||||||
|
}
|
||||||
|
updatetime = get_ctime(updatemeta, false); // not overcheck
|
||||||
|
if(0 != updatetime){
|
||||||
|
SetCtime(updatetime, true);
|
||||||
|
}
|
||||||
|
bool is_pending = !upload_id.empty();
|
||||||
|
|
||||||
return is_pending;
|
return is_pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
// global function in s3fs.cpp
|
// global function in s3fs.cpp
|
||||||
int put_headers(const char* path, headers_t& meta, bool is_copy);
|
int put_headers(const char* path, headers_t& meta, bool is_copy, bool update_mtime);
|
||||||
|
|
||||||
int FdEntity::UploadPendingMeta()
|
int FdEntity::UploadPendingMeta()
|
||||||
{
|
{
|
||||||
AutoLock auto_lock(&fdent_lock);
|
AutoLock auto_lock(&fdent_lock);
|
||||||
|
|
||||||
int result = 0;
|
// put headers, no need to update mtime to avoid dead lock
|
||||||
for(headers_list_t::const_iterator iter = pending_headers.begin(); iter != pending_headers.end(); ++iter){
|
int result = put_headers(path.c_str(), orgmeta, true, false);
|
||||||
// [NOTE]
|
if(0 != result){
|
||||||
// orgmeta will be updated sequentially.
|
S3FS_PRN_ERR("failed to put header after flushing file(%s) by(%d).", path.c_str(), result);
|
||||||
headers_t putmeta = orgmeta;
|
|
||||||
merge_headers(putmeta, *iter, true); // overwrite all keys
|
|
||||||
merge_headers(orgmeta, *iter, false); // overwrite existing keys only
|
|
||||||
|
|
||||||
// [NOTE]
|
|
||||||
// this is special cases, we remove the key which has empty values.
|
|
||||||
for(headers_t::iterator hiter = putmeta.begin(); hiter != putmeta.end(); ){
|
|
||||||
if(hiter->second.empty()){
|
|
||||||
if(orgmeta.end() != orgmeta.find(hiter->first)){
|
|
||||||
orgmeta.erase(hiter->first);
|
|
||||||
}
|
|
||||||
putmeta.erase(hiter++);
|
|
||||||
}else{
|
|
||||||
++hiter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update ctime/mtime
|
|
||||||
time_t updatetime = get_mtime((*iter), false); // not overcheck
|
|
||||||
if(0 != updatetime){
|
|
||||||
SetMtime(updatetime, true);
|
|
||||||
}
|
|
||||||
updatetime = get_ctime((*iter), false); // not overcheck
|
|
||||||
if(0 != updatetime){
|
|
||||||
SetCtime(updatetime, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// put headers
|
|
||||||
int one_result = put_headers(path.c_str(), putmeta, true);
|
|
||||||
if(0 != one_result){
|
|
||||||
S3FS_PRN_ERR("failed to put header after flushing file(%s) by(%d).", path.c_str(), one_result);
|
|
||||||
result = one_result; // keep lastest result code
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pending_headers.clear();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,6 @@ class FdEntity
|
|||||||
std::string cachepath; // local cache file path
|
std::string cachepath; // local cache file path
|
||||||
// (if this is empty, does not load/save pagelist.)
|
// (if this is empty, does not load/save pagelist.)
|
||||||
std::string mirrorpath; // mirror file path to local cache file path
|
std::string mirrorpath; // mirror file path to local cache file path
|
||||||
headers_list_t pending_headers;// pending update headers
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int FillFile(int fd, unsigned char byte, off_t size, off_t start);
|
static int FillFile(int fd, unsigned char byte, off_t size, off_t start);
|
||||||
|
@ -36,7 +36,6 @@ struct header_nocase_cmp : public std::binary_function<std::string, std::string,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
typedef std::map<std::string, std::string, header_nocase_cmp> headers_t;
|
typedef std::map<std::string, std::string, header_nocase_cmp> headers_t;
|
||||||
typedef std::list<headers_t> headers_list_t;
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Functions
|
// Functions
|
||||||
|
@ -105,7 +105,7 @@ static const std::string aws_secretkey = "AWSSecretKey";
|
|||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Global functions : prototype
|
// Global functions : prototype
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
int put_headers(const char* path, headers_t& meta, bool is_copy); // [NOTE] global function because this is called from FdEntity class
|
int put_headers(const char* path, headers_t& meta, bool is_copy, bool update_mtime = true); // [NOTE] global function because this is called from FdEntity class
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Static functions : prototype
|
// Static functions : prototype
|
||||||
@ -709,7 +709,7 @@ static FdEntity* get_local_fent(AutoFdEntity& autoent, const char* path, bool is
|
|||||||
// ow_sse_flg is for over writing sse header by use_sse option.
|
// ow_sse_flg is for over writing sse header by use_sse option.
|
||||||
// @return fuse return code
|
// @return fuse return code
|
||||||
//
|
//
|
||||||
int put_headers(const char* path, headers_t& meta, bool is_copy)
|
int put_headers(const char* path, headers_t& meta, bool is_copy, bool update_mtime)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
S3fsCurl s3fscurl(true);
|
S3fsCurl s3fscurl(true);
|
||||||
@ -739,7 +739,7 @@ int put_headers(const char* path, headers_t& meta, bool is_copy)
|
|||||||
// [NOTE]
|
// [NOTE]
|
||||||
// if path is 'dir/', it does not have cache(could not open file for directory stat)
|
// if path is 'dir/', it does not have cache(could not open file for directory stat)
|
||||||
//
|
//
|
||||||
if('/' != path[strlen(path) - 1]){
|
if(update_mtime && '/' != path[strlen(path) - 1] ){
|
||||||
AutoFdEntity autoent;
|
AutoFdEntity autoent;
|
||||||
FdEntity* ent;
|
FdEntity* ent;
|
||||||
if(NULL == (ent = autoent.ExistOpen(path, -1, !FdManager::IsCacheDir()))){
|
if(NULL == (ent = autoent.ExistOpen(path, -1, !FdManager::IsCacheDir()))){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user