Fixed a bug about move file over limit of ensure space

This commit is contained in:
Takeshi Nakatani
2020-08-02 13:37:06 +00:00
committed by Andrew Gaul
parent a23d02923c
commit 2bb745cdd7
6 changed files with 350 additions and 82 deletions

View File

@ -1803,13 +1803,15 @@ bool FdEntity::GetStats(struct stat& st, bool lock_already_held)
return true;
}
int FdEntity::SetCtime(time_t time)
int FdEntity::SetCtime(time_t time, bool lock_already_held)
{
AutoLock auto_lock(&fdent_lock, lock_already_held ? AutoLock::ALREADY_LOCKED : AutoLock::NONE);
S3FS_PRN_INFO3("[path=%s][fd=%d][time=%lld]", path.c_str(), fd, static_cast<long long>(time));
if(-1 == time){
return 0;
}
AutoLock auto_lock(&fdent_lock);
orgmeta["x-amz-meta-ctime"] = str(time);
return 0;
}
@ -1884,6 +1886,25 @@ bool FdEntity::GetSize(off_t& size)
return true;
}
bool FdEntity::GetXattr(string& xattr)
{
AutoLock auto_lock(&fdent_lock);
headers_t::const_iterator iter = orgmeta.find("x-amz-meta-xattr");
if(iter == orgmeta.end()){
return false;
}
xattr = iter->second;
return true;
}
bool FdEntity::SetXattr(const std::string& xattr)
{
AutoLock auto_lock(&fdent_lock);
orgmeta["x-amz-meta-xattr"] = xattr;
return true;
}
bool FdEntity::SetMode(mode_t mode)
{
AutoLock auto_lock(&fdent_lock);
@ -2171,6 +2192,7 @@ int FdEntity::NoCachePreMultipartPost()
// initialize multipart upload values
upload_id.erase();
etaglist.clear();
pending_headers.clear();
S3fsCurl s3fscurl(true);
int result;
@ -2377,6 +2399,11 @@ int FdEntity::RowFlush(const char* tpath, bool force_sync)
// So the file has already been removed, skip error.
S3FS_PRN_ERR("failed to truncate file(%d) to zero, but continue...", fd);
}
// put pading headers
if(0 != (result = UploadPendingMeta())){
return result;
}
}
if(0 == result){
@ -2577,6 +2604,84 @@ ssize_t FdEntity::Write(const char* bytes, off_t start, size_t size)
return wsize;
}
// [NOTE]
// Returns true if merged to orgmeta.
// If true is returned, the caller can update the header.
// If it is false, do not update the header because multipart upload is in progress.
// In this case, the header is pending internally and is updated after the upload
// is complete(flush file).
//
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;
}
return is_pending;
}
// global function in s3fs.cpp
int put_headers(const char* path, headers_t& meta, bool is_copy);
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
}
}
pending_headers.clear();
return result;
}
//------------------------------------------------
// FdManager symbol
//------------------------------------------------