Fixed a bug about move file over limit of ensure space
This commit is contained in:
committed by
Andrew Gaul
parent
a23d02923c
commit
2bb745cdd7
111
src/fdcache.cpp
111
src/fdcache.cpp
@ -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
|
||||
//------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user