diff --git a/src/fdcache_entity.cpp b/src/fdcache_entity.cpp index 7b01dea..99a2db2 100644 --- a/src/fdcache_entity.cpp +++ b/src/fdcache_entity.cpp @@ -1032,7 +1032,6 @@ int FdEntity::NoCachePreMultipartPost() // initialize multipart upload values upload_id.erase(); etaglist.clear(); - pending_headers.clear(); S3fsCurl s3fscurl(true); int result; @@ -1457,70 +1456,43 @@ bool FdEntity::MergeOrgMeta(headers_t& updatemeta) { AutoLock auto_lock(&fdent_lock); - bool is_pending; - if(upload_id.empty()){ - // merge update meta - headers_t mergedmeta = orgmeta; - - merge_headers(orgmeta, updatemeta, false); // overwrite existing keys only - merge_headers(mergedmeta, updatemeta, true); // overwrite all keys - updatemeta = mergedmeta; // swap - - is_pending = false; - }else{ - // could not update meta because uploading now, then put pending. - pending_headers.push_back(updatemeta); - is_pending = true; + merge_headers(orgmeta, updatemeta, true); // overwrite all keys + // [NOTE] + // this is special cases, we remove the key which has empty values. + for(headers_t::iterator hiter = orgmeta.begin(); hiter != orgmeta.end(); ){ + if(hiter->second.empty()){ + orgmeta.erase(hiter++); + }else{ + ++hiter; + } } + 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; } // 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() { AutoLock auto_lock(&fdent_lock); - int result = 0; - for(headers_list_t::const_iterator iter = pending_headers.begin(); iter != pending_headers.end(); ++iter){ - // [NOTE] - // orgmeta will be updated sequentially. - 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 - } + // put headers, no need to update mtime to avoid dead lock + int result = put_headers(path.c_str(), orgmeta, true, false); + if(0 != result){ + S3FS_PRN_ERR("failed to put header after flushing file(%s) by(%d).", path.c_str(), result); } - pending_headers.clear(); return result; } diff --git a/src/fdcache_entity.h b/src/fdcache_entity.h index 19cfcd2..293fa91 100644 --- a/src/fdcache_entity.h +++ b/src/fdcache_entity.h @@ -51,7 +51,6 @@ class FdEntity std::string cachepath; // local cache file path // (if this is empty, does not load/save pagelist.) std::string mirrorpath; // mirror file path to local cache file path - headers_list_t pending_headers;// pending update headers private: static int FillFile(int fd, unsigned char byte, off_t size, off_t start); diff --git a/src/metaheader.h b/src/metaheader.h index 0ae19e3..1022eeb 100644 --- a/src/metaheader.h +++ b/src/metaheader.h @@ -36,7 +36,6 @@ struct header_nocase_cmp : public std::binary_function headers_t; -typedef std::list headers_list_t; //------------------------------------------------------------------- // Functions diff --git a/src/s3fs.cpp b/src/s3fs.cpp index 07ade58..99462ff 100644 --- a/src/s3fs.cpp +++ b/src/s3fs.cpp @@ -105,7 +105,7 @@ static const std::string aws_secretkey = "AWSSecretKey"; //------------------------------------------------------------------- // 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 @@ -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. // @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; S3fsCurl s3fscurl(true); @@ -739,7 +739,7 @@ int put_headers(const char* path, headers_t& meta, bool is_copy) // [NOTE] // 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; FdEntity* ent; if(NULL == (ent = autoent.ExistOpen(path, -1, !FdManager::IsCacheDir()))){