mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-12-23 01:08:54 +00:00
Fixed not to call Flush even if the file size is increased (#1887)
Changed s3fs_truncate function. This change reduces the number of file uploads if the file size is changed. On macOS, I have found that the truncate call when "size=0" cannot reflect the file size.(This reason is not understood...) To avoid this, only when "size=0", the flush method is called as before. Other than that, I found a bug in FdEntity::Open() and fixed it. Fixes #1875.
This commit is contained in:
parent
4dfe2bfdd7
commit
839a33de49
@ -553,6 +553,11 @@ FdEntity* FdManager::Open(int& fd, const char* path, headers_t* pmeta, off_t siz
|
||||
// found
|
||||
ent = iter->second;
|
||||
|
||||
// [NOTE]
|
||||
// Even if getting the request to change the size of modifying
|
||||
// file to small, we do not change it. Because if it will change,
|
||||
// test_open_second_fd test will be failed.
|
||||
//
|
||||
if(ent->IsModified()){
|
||||
// If the file is being modified and it's size is larger than size parameter, it will not be resized.
|
||||
off_t cur_size = 0;
|
||||
|
@ -426,7 +426,7 @@ int FdEntity::Open(const headers_t* pmeta, off_t size, time_t time, int flags, A
|
||||
// check only file size(do not need to save cfs and time.
|
||||
if(0 <= size && pagelist.Size() != size){
|
||||
// truncate temporary file size
|
||||
if(-1 == ftruncate(physical_fd, size)){
|
||||
if(-1 == ftruncate(physical_fd, size) || -1 == fsync(physical_fd)){
|
||||
S3FS_PRN_ERR("failed to truncate temporary file(physical_fd=%d) by errno(%d).", physical_fd, errno);
|
||||
return -errno;
|
||||
}
|
||||
@ -440,7 +440,7 @@ int FdEntity::Open(const headers_t* pmeta, off_t size, time_t time, int flags, A
|
||||
off_t new_size = (0 <= size ? size : size_orgmeta);
|
||||
if(pmeta){
|
||||
orgmeta = *pmeta;
|
||||
new_size = get_size(orgmeta);
|
||||
size_orgmeta = get_size(orgmeta);
|
||||
}
|
||||
if(new_size < size_orgmeta){
|
||||
size_orgmeta = new_size;
|
||||
|
45
src/s3fs.cpp
45
src/s3fs.cpp
@ -2168,20 +2168,38 @@ static int s3fs_truncate(const char* _path, off_t size)
|
||||
|
||||
// Get file information
|
||||
if(0 == (result = get_object_attribute(path, NULL, &meta))){
|
||||
// Exists -> Get file(with size)
|
||||
// File exists
|
||||
|
||||
// [NOTE]
|
||||
// If the file exists, the file has already been opened by FUSE before
|
||||
// truncate is called. Then the call below will change the file size.
|
||||
// (When an already open file is changed the file size, FUSE will not
|
||||
// reopen it.)
|
||||
// The Flush is called before this file is closed, so there is no need
|
||||
// to do it here.
|
||||
//
|
||||
if(NULL == (ent = autoent.Open(path, &meta, size, -1, O_RDWR, false, true, AutoLock::NONE))){
|
||||
S3FS_PRN_ERR("could not open file(%s): errno=%d", path, errno);
|
||||
return -EIO;
|
||||
}
|
||||
if(0 != (result = ent->Load(0, size, AutoLock::NONE))){
|
||||
S3FS_PRN_ERR("could not download file(%s): result=%d", path, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
ent->UpdateCtime();
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// [NOTE]
|
||||
// Only for macos, this truncate calls to "size=0" do not reflect size.
|
||||
// The cause is unknown now, but it can be avoided by flushing the file.
|
||||
//
|
||||
if(0 == size){
|
||||
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), true))){
|
||||
S3FS_PRN_ERR("could not upload file(%s): result=%d", path, result);
|
||||
return result;
|
||||
}
|
||||
StatCache::getStatCacheData()->DelStat(path);
|
||||
}
|
||||
#endif
|
||||
|
||||
}else{
|
||||
// Not found -> Make tmpfile(with size)
|
||||
|
||||
struct fuse_context* pcxt;
|
||||
if(NULL == (pcxt = fuse_get_context())){
|
||||
return -EIO;
|
||||
@ -2198,15 +2216,12 @@ static int s3fs_truncate(const char* _path, off_t size)
|
||||
S3FS_PRN_ERR("could not open file(%s): errno=%d", path, errno);
|
||||
return -EIO;
|
||||
}
|
||||
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), true))){
|
||||
S3FS_PRN_ERR("could not upload file(%s): result=%d", path, result);
|
||||
return result;
|
||||
}
|
||||
StatCache::getStatCacheData()->DelStat(path);
|
||||
}
|
||||
|
||||
// upload
|
||||
if(0 != (result = ent->Flush(autoent.GetPseudoFd(), true))){
|
||||
S3FS_PRN_ERR("could not upload file(%s): result=%d", path, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
StatCache::getStatCacheData()->DelStat(path);
|
||||
S3FS_MALLOCTRIM(0);
|
||||
|
||||
return result;
|
||||
|
Loading…
Reference in New Issue
Block a user