Merge pull request #1125 from ggtakec/fix_nocopyapi_copy

Fixed simple copy with nocpoyapi and modify flag in fdcache
This commit is contained in:
Takeshi Nakatani 2019-08-11 17:30:04 +09:00 committed by GitHub
commit 2a779df4fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 133 additions and 87 deletions

View File

@ -244,9 +244,16 @@ void PageList::FreeList(fdpage_list_t& list)
list.clear(); list.clear();
} }
PageList::PageList(off_t size, bool is_loaded) PageList::PageList(off_t size, bool is_loaded, bool is_modified)
{ {
Init(size, is_loaded); Init(size, is_loaded, is_modified);
}
PageList::PageList(const PageList& other)
{
for(fdpage_list_t::const_iterator iter = other.pages.begin(); iter != other.pages.end(); ++iter){
pages.push_back(*iter);
}
} }
PageList::~PageList() PageList::~PageList()
@ -259,10 +266,10 @@ void PageList::Clear()
PageList::FreeList(pages); PageList::FreeList(pages);
} }
bool PageList::Init(off_t size, bool is_loaded) bool PageList::Init(off_t size, bool is_loaded, bool is_modified)
{ {
Clear(); Clear();
fdpage page(0, size, is_loaded); fdpage page(0, size, is_loaded, is_modified);
pages.push_back(page); pages.push_back(page);
return true; return true;
} }
@ -276,23 +283,33 @@ off_t PageList::Size() const
return riter->next(); return riter->next();
} }
bool PageList::Compress() bool PageList::Compress(bool force_modified)
{ {
bool is_first = true; bool is_first = true;
bool is_last_loaded = false; bool is_last_loaded = false;
bool is_last_modified = false;
for(fdpage_list_t::iterator iter = pages.begin(); iter != pages.end(); ){ for(fdpage_list_t::iterator iter = pages.begin(); iter != pages.end(); ){
if(is_first){ if(is_first){
is_first = false; is_first = false;
is_last_loaded = iter->loaded; is_last_loaded = force_modified ? true : iter->loaded;
is_last_modified = iter->modified;
++iter; ++iter;
}else{ }else{
if(is_last_loaded == iter->loaded){ if(is_last_modified == iter->modified){
if(force_modified || is_last_loaded == iter->loaded){
fdpage_list_t::iterator biter = iter; fdpage_list_t::iterator biter = iter;
--biter; --biter;
biter->bytes += iter->bytes; biter->bytes += iter->bytes;
iter = pages.erase(iter); iter = pages.erase(iter);
}else{ }else{
is_last_loaded = iter->loaded; is_last_loaded = iter->loaded;
is_last_modified = iter->modified;
++iter;
}
}else{
is_last_loaded = force_modified ? true : iter->loaded;
is_last_modified = iter->modified;
++iter; ++iter;
} }
} }
@ -307,7 +324,7 @@ bool PageList::Parse(off_t new_pos)
// nothing to do // nothing to do
return true; return true;
}else if(iter->offset < new_pos && new_pos < iter->next()){ }else if(iter->offset < new_pos && new_pos < iter->next()){
fdpage page(iter->offset, new_pos - iter->offset, iter->loaded); fdpage page(iter->offset, new_pos - iter->offset, iter->loaded, false);
iter->bytes -= (new_pos - iter->offset); iter->bytes -= (new_pos - iter->offset);
iter->offset = new_pos; iter->offset = new_pos;
pages.insert(iter, page); pages.insert(iter, page);
@ -317,16 +334,16 @@ bool PageList::Parse(off_t new_pos)
return false; return false;
} }
bool PageList::Resize(off_t size, bool is_loaded) bool PageList::Resize(off_t size, bool is_loaded, bool is_modified)
{ {
off_t total = Size(); off_t total = Size();
if(0 == total){ if(0 == total){
Init(size, is_loaded); Init(size, is_loaded, is_modified);
}else if(total < size){ }else if(total < size){
// add new area // add new area
fdpage page(total, (size - total), is_loaded); fdpage page(total, (size - total), is_loaded, is_modified);
pages.push_back(page); pages.push_back(page);
}else if(size < total){ }else if(size < total){
@ -365,22 +382,22 @@ bool PageList::IsPageLoaded(off_t start, off_t size) const
return true; return true;
} }
bool PageList::SetPageLoadedStatus(off_t start, off_t size, bool is_loaded, bool is_compress) bool PageList::SetPageLoadedStatus(off_t start, off_t size, bool is_loaded, bool is_modified, bool is_compress)
{ {
off_t now_size = Size(); off_t now_size = Size();
if(now_size <= start){ if(now_size <= start){
if(now_size < start){ if(now_size < start){
// add // add
Resize(start, false); Resize(start, false, is_modified); // set modified flag from now end pos to specified start pos.
} }
Resize(start + size, is_loaded); Resize(start + size, is_loaded, is_modified);
}else if(now_size <= start + size){ }else if(now_size <= start + size){
// cut // cut
Resize(start, false); Resize(start, false, false); // not changed loaded/modified flags in existing area.
// add // add
Resize(start + size, is_loaded); Resize(start + size, is_loaded, is_modified);
}else{ }else{
// start-size are inner pages area // start-size are inner pages area
@ -396,6 +413,7 @@ bool PageList::SetPageLoadedStatus(off_t start, off_t size, bool is_loaded, bool
break; break;
}else{ }else{
iter->loaded = is_loaded; iter->loaded = is_loaded;
iter->modified = is_modified;
} }
} }
} }
@ -407,7 +425,7 @@ bool PageList::FindUnloadedPage(off_t start, off_t& resstart, off_t& ressize) co
{ {
for(fdpage_list_t::const_iterator iter = pages.begin(); iter != pages.end(); ++iter){ for(fdpage_list_t::const_iterator iter = pages.begin(); iter != pages.end(); ++iter){
if(start <= iter->end()){ if(start <= iter->end()){
if(!iter->loaded){ if(!iter->loaded && !iter->modified){ // Do not load unloaded and modified areas
resstart = iter->offset; resstart = iter->offset;
ressize = iter->bytes; ressize = iter->bytes;
return true; return true;
@ -428,7 +446,7 @@ off_t PageList::GetTotalUnloadedPageSize(off_t start, off_t size) const
if(next <= iter->offset){ if(next <= iter->offset){
break; break;
} }
if(iter->loaded){ if(iter->loaded || iter->modified){
continue; continue;
} }
off_t tmpsize; off_t tmpsize;
@ -467,8 +485,8 @@ int PageList::GetUnloadedPages(fdpage_list_t& unloaded_list, off_t start, off_t
if(next <= iter->offset){ if(next <= iter->offset){
break; break;
} }
if(iter->loaded){ if(iter->loaded || iter->modified){
continue; // already loaded continue; // already loaded or modified
} }
// page area // page area
@ -482,13 +500,33 @@ int PageList::GetUnloadedPages(fdpage_list_t& unloaded_list, off_t start, off_t
// merge to before page // merge to before page
riter->bytes += page_size; riter->bytes += page_size;
}else{ }else{
fdpage page(page_start, page_size, false); fdpage page(page_start, page_size, false, false);
unloaded_list.push_back(page); unloaded_list.push_back(page);
} }
} }
return unloaded_list.size(); return unloaded_list.size();
} }
bool PageList::IsModified(void) const
{
for(fdpage_list_t::const_iterator iter = pages.begin(); iter != pages.end(); ++iter){
if(iter->modified){
return true;
}
}
return false;
}
bool PageList::ClearAllModified(void)
{
for(fdpage_list_t::iterator iter = pages.begin(); iter != pages.end(); ++iter){
if(iter->modified){
iter->modified = false;
}
}
return Compress();
}
bool PageList::Serialize(CacheFileStat& file, bool is_output) bool PageList::Serialize(CacheFileStat& file, bool is_output)
{ {
if(!file.Open()){ if(!file.Open()){
@ -502,7 +540,7 @@ bool PageList::Serialize(CacheFileStat& file, bool is_output)
ssall << Size(); ssall << Size();
for(fdpage_list_t::iterator iter = pages.begin(); iter != pages.end(); ++iter){ for(fdpage_list_t::iterator iter = pages.begin(); iter != pages.end(); ++iter){
ssall << "\n" << iter->offset << ":" << iter->bytes << ":" << (iter->loaded ? "1" : "0"); ssall << "\n" << iter->offset << ":" << iter->bytes << ":" << (iter->loaded ? "1" : "0") << ":" << (iter->modified ? "1" : "0");
} }
string strall = ssall.str(); string strall = ssall.str();
@ -523,7 +561,7 @@ bool PageList::Serialize(CacheFileStat& file, bool is_output)
} }
if(0 >= st.st_size){ if(0 >= st.st_size){
// nothing // nothing
Init(0, false); Init(0, false, false);
return true; return true;
} }
char* ptmp = new char[st.st_size + 1]; char* ptmp = new char[st.st_size + 1];
@ -571,8 +609,14 @@ bool PageList::Serialize(CacheFileStat& file, bool is_output)
break; break;
} }
bool is_loaded = (1 == s3fs_strtoofft(part.c_str()) ? true : false); bool is_loaded = (1 == s3fs_strtoofft(part.c_str()) ? true : false);
bool is_modified;
if(!getline(ssparts, part, ':')){
is_modified = false; // old version does not have this part.
}else{
is_modified = (1 == s3fs_strtoofft(part.c_str()) ? true : false);
}
// add new area // add new area
SetPageLoadedStatus(offset, size, is_loaded); SetPageLoadedStatus(offset, size, is_loaded, is_modified);
} }
delete[] ptmp; delete[] ptmp;
if(is_err){ if(is_err){
@ -597,7 +641,7 @@ void PageList::Dump()
S3FS_PRN_DBG("pages = {"); S3FS_PRN_DBG("pages = {");
for(fdpage_list_t::iterator iter = pages.begin(); iter != pages.end(); ++iter, ++cnt){ for(fdpage_list_t::iterator iter = pages.begin(); iter != pages.end(); ++iter, ++cnt){
S3FS_PRN_DBG(" [%08d] -> {%014lld - %014lld : %s}", cnt, static_cast<long long int>(iter->offset), static_cast<long long int>(iter->bytes), iter->loaded ? "true" : "false"); S3FS_PRN_DBG(" [%08d] -> {%014lld - %014lld : %s / %s}", cnt, static_cast<long long int>(iter->offset), static_cast<long long int>(iter->bytes), iter->loaded ? "loaded" : "unloaded", iter->modified ? "modified" : "not modified");
} }
S3FS_PRN_DBG("}"); S3FS_PRN_DBG("}");
} }
@ -624,7 +668,7 @@ int FdEntity::FillFile(int fd, unsigned char byte, off_t size, off_t start)
//------------------------------------------------ //------------------------------------------------
FdEntity::FdEntity(const char* tpath, const char* cpath) FdEntity::FdEntity(const char* tpath, const char* cpath)
: is_lock_init(false), refcnt(0), path(SAFESTRPTR(tpath)), : is_lock_init(false), refcnt(0), path(SAFESTRPTR(tpath)),
fd(-1), pfile(NULL), size_orgmeta(0), upload_id(""), mp_start(0), mp_size(0), is_modify(false), fd(-1), pfile(NULL), size_orgmeta(0), upload_id(""), mp_start(0), mp_size(0),
cachepath(SAFESTRPTR(cpath)), mirrorpath("") cachepath(SAFESTRPTR(cpath)), mirrorpath("")
{ {
try{ try{
@ -681,11 +725,10 @@ void FdEntity::Clear()
mirrorpath.erase(); mirrorpath.erase();
} }
} }
pagelist.Init(0, false); pagelist.Init(0, false, false);
refcnt = 0; refcnt = 0;
path = ""; path = "";
cachepath = ""; cachepath = "";
is_modify = false;
} }
void FdEntity::Close() void FdEntity::Close()
@ -824,7 +867,7 @@ int FdEntity::Open(headers_t* pmeta, off_t size, time_t time, bool no_fd_lock_wa
return -EIO; return -EIO;
} }
// resize page list // resize page list
if(!pagelist.Resize(size, false)){ if(!pagelist.Resize(size, false, false)){
S3FS_PRN_ERR("failed to truncate temporary file information(%d).", fd); S3FS_PRN_ERR("failed to truncate temporary file information(%d).", fd);
if(0 < refcnt){ if(0 < refcnt){
refcnt--; refcnt--;
@ -875,13 +918,13 @@ int FdEntity::Open(headers_t* pmeta, off_t size, time_t time, bool no_fd_lock_wa
// check size, st_size, loading stat file // check size, st_size, loading stat file
if(-1 == size){ if(-1 == size){
if(st.st_size != pagelist.Size()){ if(st.st_size != pagelist.Size()){
pagelist.Resize(st.st_size, false); pagelist.Resize(st.st_size, false, false);
need_save_csf = true; // need to update page info need_save_csf = true; // need to update page info
} }
size = st.st_size; size = st.st_size;
}else{ }else{
if(size != pagelist.Size()){ if(size != pagelist.Size()){
pagelist.Resize(size, false); pagelist.Resize(size, false, false);
need_save_csf = true; // need to update page info need_save_csf = true; // need to update page info
} }
if(size != st.st_size){ if(size != st.st_size){
@ -898,9 +941,9 @@ int FdEntity::Open(headers_t* pmeta, off_t size, time_t time, bool no_fd_lock_wa
need_save_csf = true; // need to update page info need_save_csf = true; // need to update page info
if(-1 == size){ if(-1 == size){
size = 0; size = 0;
pagelist.Init(0, false); pagelist.Init(0, false, false);
}else{ }else{
pagelist.Resize(size, false); pagelist.Resize(size, false, false);
is_truncate = true; is_truncate = true;
} }
} }
@ -937,9 +980,9 @@ int FdEntity::Open(headers_t* pmeta, off_t size, time_t time, bool no_fd_lock_wa
} }
if(-1 == size){ if(-1 == size){
size = 0; size = 0;
pagelist.Init(0, false); pagelist.Init(0, false, false);
}else{ }else{
pagelist.Resize(size, false); pagelist.Resize(size, false, false);
is_truncate = true; is_truncate = true;
} }
} }
@ -965,7 +1008,6 @@ int FdEntity::Open(headers_t* pmeta, off_t size, time_t time, bool no_fd_lock_wa
// init internal data // init internal data
refcnt = 1; refcnt = 1;
is_modify = false;
// set original headers and size in it. // set original headers and size in it.
if(pmeta){ if(pmeta){
@ -1019,9 +1061,6 @@ bool FdEntity::OpenAndLoadAll(headers_t* pmeta, off_t* size, bool force_load)
S3FS_PRN_ERR("could not download, result(%d)", result); S3FS_PRN_ERR("could not download, result(%d)", result);
return false; return false;
} }
if(is_modify){
is_modify = false;
}
if(size){ if(size){
*size = pagelist.Size(); *size = pagelist.Size();
} }
@ -1176,7 +1215,7 @@ bool FdEntity::SetAllStatus(bool is_loaded)
return false; return false;
} }
// Reinit // Reinit
pagelist.Init(st.st_size, is_loaded); pagelist.Init(st.st_size, is_loaded, false);
return true; return true;
} }
@ -1208,7 +1247,6 @@ int FdEntity::Load(off_t start, off_t size, bool lock_already_held)
// original file size(on S3) is smaller than request. // original file size(on S3) is smaller than request.
need_load_size = (iter->next() <= size_orgmeta ? iter->bytes : (size_orgmeta - iter->offset)); need_load_size = (iter->next() <= size_orgmeta ? iter->bytes : (size_orgmeta - iter->offset));
} }
off_t over_size = iter->bytes - need_load_size;
// download // download
if(S3fsCurl::GetMultipartSize() <= need_load_size && !nomultipart){ if(S3fsCurl::GetMultipartSize() <= need_load_size && !nomultipart){
@ -1226,19 +1264,8 @@ int FdEntity::Load(off_t start, off_t size, bool lock_already_held)
if(0 != result){ if(0 != result){
break; break;
} }
// initialize for the area of over original size
if(0 < over_size){
if(0 != (result = FdEntity::FillFile(fd, 0, over_size, iter->offset + need_load_size))){
S3FS_PRN_ERR("failed to fill rest bytes for fd(%d). errno(%d)", fd, result);
break;
}
// set modify flag
is_modify = false;
}
// Set loaded flag // Set loaded flag
pagelist.SetPageLoadedStatus(iter->offset, iter->bytes, true); pagelist.SetPageLoadedStatus(iter->offset, iter->bytes, true, false);
} }
PageList::FreeList(unloaded_list); PageList::FreeList(unloaded_list);
} }
@ -1363,8 +1390,6 @@ int FdEntity::NoCacheLoadAndPost(off_t start, off_t size)
S3FS_PRN_ERR("failed to fill rest bytes for fd(%d). errno(%d)", tmpfd, result); S3FS_PRN_ERR("failed to fill rest bytes for fd(%d). errno(%d)", tmpfd, result);
break; break;
} }
// set modify flag
is_modify = false;
} }
}else{ }else{
@ -1384,18 +1409,19 @@ int FdEntity::NoCacheLoadAndPost(off_t start, off_t size)
// set loaded flag // set loaded flag
if(!iter->loaded){ if(!iter->loaded){
if(iter->offset < start){ if(iter->offset < start){
fdpage page(iter->offset, start - iter->offset, iter->loaded); fdpage page(iter->offset, start - iter->offset, iter->loaded, false);
iter->bytes -= (start - iter->offset); iter->bytes -= (start - iter->offset);
iter->offset = start; iter->offset = start;
pagelist.pages.insert(iter, page); pagelist.pages.insert(iter, page);
} }
if(0 != size && start + size < iter->next()){ if(0 != size && start + size < iter->next()){
fdpage page(iter->offset, start + size - iter->offset, true); fdpage page(iter->offset, start + size - iter->offset, true, false);
iter->bytes -= (start + size - iter->offset); iter->bytes -= (start + size - iter->offset);
iter->offset = start + size; iter->offset = start + size;
pagelist.pages.insert(iter, page); pagelist.pages.insert(iter, page);
}else{ }else{
iter->loaded = true; iter->loaded = true;
iter->modified = false;
} }
} }
} }
@ -1494,7 +1520,7 @@ int FdEntity::RowFlush(const char* tpath, bool force_sync)
} }
AutoLock auto_lock(&fdent_data_lock); AutoLock auto_lock(&fdent_data_lock);
if(!force_sync && !is_modify){ if(!force_sync && !pagelist.IsModified()){
// nothing to update. // nothing to update.
return 0; return 0;
} }
@ -1600,7 +1626,7 @@ int FdEntity::RowFlush(const char* tpath, bool force_sync)
} }
if(0 == result){ if(0 == result){
is_modify = false; pagelist.ClearAllModified();
} }
return result; return result;
} }
@ -1613,9 +1639,9 @@ bool FdEntity::ReserveDiskSpace(off_t size)
return true; return true;
} }
if(!is_modify){ if(!pagelist.IsModified()){
// try to clear all cache for this fd. // try to clear all cache for this fd.
pagelist.Init(pagelist.Size(), false); pagelist.Init(pagelist.Size(), false, false);
if(-1 == ftruncate(fd, 0) || -1 == ftruncate(fd, pagelist.Size())){ if(-1 == ftruncate(fd, 0) || -1 == ftruncate(fd, pagelist.Size())){
S3FS_PRN_ERR("failed to truncate temporary file(%d).", fd); S3FS_PRN_ERR("failed to truncate temporary file(%d).", fd);
return false; return false;
@ -1641,7 +1667,7 @@ ssize_t FdEntity::Read(char* bytes, off_t start, size_t size, bool force_load)
AutoLock auto_lock(&fdent_data_lock); AutoLock auto_lock(&fdent_data_lock);
if(force_load){ if(force_load){
pagelist.SetPageLoadedStatus(start, size, false); pagelist.SetPageLoadedStatus(start, size, false, false);
} }
ssize_t rsize; ssize_t rsize;
@ -1711,7 +1737,7 @@ ssize_t FdEntity::Write(const char* bytes, off_t start, size_t size)
return -EIO; return -EIO;
} }
// add new area // add new area
pagelist.SetPageLoadedStatus(pagelist.Size(), start - pagelist.Size(), false); pagelist.SetPageLoadedStatus(pagelist.Size(), start - pagelist.Size(), false, true);
} }
int result = 0; int result = 0;
@ -1755,11 +1781,8 @@ ssize_t FdEntity::Write(const char* bytes, off_t start, size_t size)
S3FS_PRN_ERR("pwrite failed. errno(%d)", errno); S3FS_PRN_ERR("pwrite failed. errno(%d)", errno);
return -errno; return -errno;
} }
if(!is_modify){
is_modify = true;
}
if(0 < wsize){ if(0 < wsize){
pagelist.SetPageLoadedStatus(start, wsize, true); pagelist.SetPageLoadedStatus(start, wsize, true, true);
} }
// Load uninitialized area which starts from (start + size) to EOF after writing. // Load uninitialized area which starts from (start + size) to EOF after writing.
@ -1803,7 +1826,7 @@ void FdEntity::CleanupCache()
return; return;
} }
if (is_modify) { if(pagelist.IsModified()){
// cache is not committed to s3, cannot cleanup // cache is not committed to s3, cannot cleanup
return; return;
} }
@ -2152,6 +2175,10 @@ FdEntity* FdManager::Open(const char* path, headers_t* pmeta, off_t size, time_t
// found // found
ent = (*iter).second; ent = (*iter).second;
ent->Dup(); ent->Dup();
if(ent->IsModified()){
// If the file is being modified, it will not be resized.
size = -1;
}
close = true; close = true;
}else if(is_create){ }else if(is_create){

View File

@ -58,9 +58,10 @@ struct fdpage
off_t offset; off_t offset;
off_t bytes; off_t bytes;
bool loaded; bool loaded;
bool modified;
fdpage(off_t start = 0, off_t size = 0, bool is_loaded = false) fdpage(off_t start = 0, off_t size = 0, bool is_loaded = false, bool is_modified = false)
: offset(start), bytes(size), loaded(is_loaded) {} : offset(start), bytes(size), loaded(is_loaded), modified(is_modified) {}
off_t next(void) const { return (offset + bytes); } off_t next(void) const { return (offset + bytes); }
off_t end(void) const { return (0 < bytes ? offset + bytes - 1 : 0); } off_t end(void) const { return (0 < bytes ? offset + bytes - 1 : 0); }
@ -72,6 +73,7 @@ class FdEntity;
// //
// Management of loading area/modifying // Management of loading area/modifying
// //
// cppcheck-suppress copyCtorAndEqOperator
class PageList class PageList
{ {
friend class FdEntity; // only one method access directly pages. friend class FdEntity; // only one method access directly pages.
@ -81,25 +83,30 @@ class PageList
private: private:
void Clear(void); void Clear(void);
bool Compress(void); bool Compress(bool force_modified = false);
bool Parse(off_t new_pos); bool Parse(off_t new_pos);
bool RawGetUnloadPageList(fdpage_list_t& dlpages, off_t offset, off_t size);
public: public:
static void FreeList(fdpage_list_t& list); static void FreeList(fdpage_list_t& list);
explicit PageList(off_t size = 0, bool is_loaded = false); explicit PageList(off_t size = 0, bool is_loaded = false, bool is_modified = false);
explicit PageList(const PageList& other);
~PageList(); ~PageList();
bool Init(off_t size, bool is_loaded); bool Init(off_t size, bool is_loaded, bool is_modified);
off_t Size(void) const; off_t Size(void) const;
bool Resize(off_t size, bool is_loaded); bool Resize(off_t size, bool is_loaded, bool is_modified);
bool IsPageLoaded(off_t start = 0, off_t size = 0) const; // size=0 is checking to end of list bool IsPageLoaded(off_t start = 0, off_t size = 0) const; // size=0 is checking to end of list
bool SetPageLoadedStatus(off_t start, off_t size, bool is_loaded = true, bool is_compress = true); bool SetPageLoadedStatus(off_t start, off_t size, bool is_loaded = true, bool is_modified = false, bool is_compress = true);
bool FindUnloadedPage(off_t start, off_t& resstart, off_t& ressize) const; bool FindUnloadedPage(off_t start, off_t& resstart, off_t& ressize) const;
off_t GetTotalUnloadedPageSize(off_t start = 0, off_t size = 0) const; // size=0 is checking to end of list off_t GetTotalUnloadedPageSize(off_t start = 0, off_t size = 0) const; // size=0 is checking to end of list
int GetUnloadedPages(fdpage_list_t& unloaded_list, off_t start = 0, off_t size = 0) const; // size=0 is checking to end of list int GetUnloadedPages(fdpage_list_t& unloaded_list, off_t start = 0, off_t size = 0) const; // size=0 is checking to end of list
bool IsModified(void) const;
bool ClearAllModified(void);
bool Serialize(CacheFileStat& file, bool is_output); bool Serialize(CacheFileStat& file, bool is_output);
void Dump(void); void Dump(void);
}; };
@ -125,7 +132,6 @@ class FdEntity
etaglist_t etaglist; // for no cached multipart uploading when no disk space etaglist_t etaglist; // for no cached multipart uploading when no disk space
off_t mp_start; // start position for no cached multipart(write method only) off_t mp_start; // start position for no cached multipart(write method only)
off_t mp_size; // size for no cached multipart(write method only) off_t mp_size; // size for no cached multipart(write method only)
bool is_modify; // if file is changed, this flag is true
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
@ -153,6 +159,7 @@ class FdEntity
const char* GetPath(void) const { return path.c_str(); } const char* GetPath(void) const { return path.c_str(); }
void SetPath(const std::string &newpath) { path = newpath; } void SetPath(const std::string &newpath) { path = newpath; }
int GetFd(void) const { return fd; } int GetFd(void) const { return fd; }
bool IsModified(void) const { return pagelist.IsModified(); }
bool GetStats(struct stat& st, bool lock_already_held = false); bool GetStats(struct stat& st, bool lock_already_held = false);
int SetCtime(time_t time); int SetCtime(time_t time);

View File

@ -512,6 +512,17 @@ function test_rm_rf_dir {
fi fi
} }
function test_copy_file {
describe "Test simple copy"
dd if=/dev/urandom of=/tmp/simple_file bs=1024 count=1
cp /tmp/simple_file copied_simple_file
cmp /tmp/simple_file copied_simple_file
rm /tmp/simple_file
rm copied_simple_file
}
function test_write_after_seek_ahead { function test_write_after_seek_ahead {
describe "Test writes succeed after a seek ahead" describe "Test writes succeed after a seek ahead"
dd if=/dev/zero of=testfile seek=1 count=1 bs=1024 dd if=/dev/zero of=testfile seek=1 count=1 bs=1024
@ -589,6 +600,7 @@ function add_all_tests {
add_tests test_mtime_file add_tests test_mtime_file
add_tests test_update_time add_tests test_update_time
add_tests test_rm_rf_dir add_tests test_rm_rf_dir
add_tests test_copy_file
add_tests test_write_after_seek_ahead add_tests test_write_after_seek_ahead
add_tests test_overwrite_existing_file_range add_tests test_overwrite_existing_file_range
add_tests test_concurrency add_tests test_concurrency