From 090c37a1c1794a79a6661625f1cafda05b9688a6 Mon Sep 17 00:00:00 2001 From: Takeshi Nakatani Date: Tue, 12 Apr 2016 18:24:36 +0000 Subject: [PATCH] Fixed writing sparsed file - #375,#379,#394 --- src/fdcache.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/fdcache.cpp b/src/fdcache.cpp index a72f845..18b1e14 100644 --- a/src/fdcache.cpp +++ b/src/fdcache.cpp @@ -728,6 +728,29 @@ int FdEntity::Open(headers_t* pmeta, ssize_t size, time_t time) if(-1 != fd){ // already opened, needs to increment refcnt. Dup(); + + // check only file size(do not need to save cfs and time. + if(0 <= size && pagelist.Size() != static_cast(size)){ + // truncate temporary file size + if(-1 == ftruncate(fd, static_cast(size))){ + S3FS_PRN_ERR("failed to truncate temporary file(%d) by errno(%d).", fd, errno); + return -EIO; + } + // resize page list + if(!pagelist.Resize(static_cast(size), false)){ + S3FS_PRN_ERR("failed to truncate temporary file information(%d).", fd); + return -EIO; + } + } + // set original headers and set size. + size_t new_size = (0 <= size ? static_cast(size) : size_orgmeta); + if(pmeta){ + orgmeta = *pmeta; + new_size = static_cast(get_size(orgmeta)); + } + if(new_size < size_orgmeta){ + size_orgmeta = new_size; + } return 0; } @@ -1057,8 +1080,12 @@ int FdEntity::Load(off_t start, size_t size) } }else{ // single request - S3fsCurl s3fscurl; - result = s3fscurl.GetObjectRequest(path.c_str(), fd, (*iter)->offset, need_load_size); + if(0 < need_load_size){ + S3fsCurl s3fscurl; + result = s3fscurl.GetObjectRequest(path.c_str(), fd, (*iter)->offset, need_load_size); + }else{ + result = 0; + } } if(0 != result){ break; @@ -1379,6 +1406,12 @@ int FdEntity::RowFlush(const char* tpath, bool force_sync) S3FS_PRN_ERR("lseek error(%d)", errno); return -errno; } + // backup upload file size + struct stat st; + memset(&st, 0, sizeof(struct stat)); + if(-1 == fstat(fd, &st)){ + S3FS_PRN_ERR("fstat is failed by errno(%d), but continue...", errno); + } if(pagelist.Size() >= static_cast(2 * S3fsCurl::GetMultipartSize()) && !nomultipart){ // default 20MB // Additional time is needed for large files @@ -1401,6 +1434,9 @@ int FdEntity::RowFlush(const char* tpath, bool force_sync) return -errno; } + // reset uploaded file size + size_orgmeta = static_cast(st.st_size); + }else{ // upload rest data if(0 < mp_size){ @@ -1498,6 +1534,17 @@ ssize_t FdEntity::Write(const char* bytes, off_t start, size_t size) } AutoLock auto_lock(&fdent_lock); + // check file size + if(pagelist.Size() < static_cast(start)){ + // grow file size + if(-1 == ftruncate(fd, static_cast(start))){ + S3FS_PRN_ERR("failed to truncate temporary file(%d).", fd); + return -EIO; + } + // add new area + pagelist.SetPageLoadedStatus(static_cast(pagelist.Size()), static_cast(start) - pagelist.Size(), false); + } + int result; ssize_t wsize;