From 82430e1079bd5ec9c79ed31dc6256d14b84d1a2d Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Fri, 9 Jun 2023 11:58:06 -0500 Subject: [PATCH] Fix moveonenospc when file opened with append mode --- src/fs_copydata_readwrite.cpp | 8 +- src/fs_mktemp.cpp | 2 +- src/fs_movefile.cpp | 154 ++++++++++++++++++++-------------- src/fs_movefile.hpp | 4 +- src/fuse_write.cpp | 50 +++-------- 5 files changed, 112 insertions(+), 106 deletions(-) diff --git a/src/fs_copydata_readwrite.cpp b/src/fs_copydata_readwrite.cpp index e2c48795..45db4bf9 100644 --- a/src/fs_copydata_readwrite.cpp +++ b/src/fs_copydata_readwrite.cpp @@ -57,8 +57,7 @@ namespace l int copydata_readwrite(const int src_fd_, const int dst_fd_, - const size_t count_, - const size_t blocksize_) + const size_t count_) { ssize_t nr; ssize_t nw; @@ -66,7 +65,7 @@ namespace l size_t totalwritten; vector buf; - bufsize = (blocksize_ * 16); + bufsize = (128 * 1024); buf.resize(bufsize); fs::lseek(src_fd_,0,SEEK_SET); @@ -108,7 +107,6 @@ namespace fs return l::copydata_readwrite(src_fd_, dst_fd_, - st.st_size, - st.st_blksize); + st.st_size); } } diff --git a/src/fs_mktemp.cpp b/src/fs_mktemp.cpp index bd4ea2cf..f705afcd 100644 --- a/src/fs_mktemp.cpp +++ b/src/fs_mktemp.cpp @@ -59,7 +59,7 @@ namespace fs fd = -1; count = MAX_ATTEMPTS; - flags = (flags_ | O_EXCL | O_CREAT); + flags = (flags_ | O_EXCL | O_CREAT | O_TRUNC); while(count-- > 0) { tmppath = generate_tmp_path(*base_); diff --git a/src/fs_movefile.cpp b/src/fs_movefile.cpp index bd9c37b6..51590a70 100644 --- a/src/fs_movefile.cpp +++ b/src/fs_movefile.cpp @@ -44,6 +44,21 @@ using std::string; using std::vector; +static +int +cleanup_flags(const int flags_) +{ + int rv; + + rv = flags_; + rv = (rv & ~O_TRUNC); + rv = (rv & ~O_CREAT); + rv = (rv & ~O_EXCL); + + return rv; +} + + namespace l { static @@ -51,82 +66,99 @@ namespace l movefile(const Policy::Create &createFunc_, const Branches::CPtr &branches_, const string &fusepath_, - int *origfd_) + int origfd_) { int rv; - int fdin; - int fdout; - int fdin_flags; - int64_t fdin_size; + int srcfd; + int dstfd; + int dstfd_flags; + int origfd_flags; + int64_t srcfd_size; string fusedir; - string fdin_path; - string fdout_temp; - vector fdout_path; - - fdin = *origfd_; + string srcfd_branch; + string srcfd_filepath; + string dstfd_filepath; + string dstfd_tmp_filepath; + vector dstfd_branch; - fdin_flags = fs::getfl(fdin); - if(fdin_flags == -1) - return -1; + srcfd = -1; + dstfd = -1; - rv = fs::findonfs(branches_,fusepath_,fdin,&fdin_path); + rv = fs::findonfs(branches_,fusepath_,origfd_,&srcfd_branch); if(rv == -1) - return -1; + return -errno; - rv = createFunc_(branches_,fusepath_,&fdout_path); + rv = createFunc_(branches_,fusepath_,&dstfd_branch); if(rv == -1) - return -1; + return -errno; - fdin_size = fs::file_size(fdin); - if(fdin_size == -1) - return -1; + origfd_flags = fs::getfl(origfd_); + if(origfd_flags == -1) + return -errno; - if(fs::has_space(fdout_path[0],fdin_size) == false) - return (errno=ENOSPC,-1); + srcfd_size = fs::file_size(origfd_); + if(srcfd_size == -1) + return -errno; + + if(fs::has_space(dstfd_branch[0],srcfd_size) == false) + return -ENOSPC; fusedir = fs::path::dirname(fusepath_); - rv = fs::clonepath(fdin_path,fdout_path[0],fusedir); + rv = fs::clonepath(srcfd_branch,dstfd_branch[0],fusedir); if(rv == -1) - return -1; - - fs::path::append(fdin_path,fusepath_); - fdin = fs::open(fdin_path,O_RDONLY); - if(fdin == -1) - return -1; + return -ENOSPC; + + srcfd_filepath = srcfd_branch; + fs::path::append(srcfd_filepath,fusepath_); + srcfd = fs::open(srcfd_filepath,O_RDONLY); + if(srcfd == -1) + return -ENOSPC; + + dstfd_filepath = dstfd_branch[0]; + fs::path::append(dstfd_filepath,fusepath_); + dstfd_tmp_filepath = dstfd_filepath; + dstfd = fs::mktemp(&dstfd_tmp_filepath,O_WRONLY); + if(dstfd == -1) + { + fs::close(srcfd); + return -ENOSPC; + } + + rv = fs::clonefile(srcfd,dstfd); + if(rv == -1) + { + fs::close(srcfd); + fs::close(dstfd); + fs::unlink(dstfd_tmp_filepath); + return -ENOSPC; + } + + rv = fs::rename(dstfd_tmp_filepath,dstfd_filepath); + if(rv == -1) + { + fs::close(srcfd); + fs::close(dstfd); + fs::unlink(dstfd_tmp_filepath); + return -ENOSPC; + } + + fs::close(srcfd); + fs::close(dstfd); + + dstfd_flags = ::cleanup_flags(origfd_flags); + rv = fs::open(dstfd_filepath,dstfd_flags); + if(rv == -1) + { + fs::unlink(dstfd_tmp_filepath); + return -ENOSPC; + } - fs::path::append(fdout_path[0],fusepath_); - fdout_temp = fdout_path[0]; - fdout = fs::mktemp(&fdout_temp,fdin_flags); - if(fdout == -1) - return -1; + fs::unlink(srcfd_filepath); - rv = fs::clonefile(fdin,fdout); - if(rv == -1) - goto cleanup; + fs::close(origfd_); - rv = fs::rename(fdout_temp,fdout_path[0]); - if(rv == -1) - goto cleanup; - - // should we care if it fails? - fs::unlink(fdin_path); - - std::swap(*origfd_,fdout); - fs::close(fdin); - fs::close(fdout); - - return 0; - - cleanup: - rv = errno; - if(fdin != -1) - fs::close(fdin); - if(fdout != -1) - fs::close(fdout); - fs::unlink(fdout_temp); - errno = rv; - return -1; + return rv; } } @@ -136,7 +168,7 @@ namespace fs movefile(const Policy::Create &policy_, const Branches::CPtr &basepaths_, const string &fusepath_, - int *origfd_) + int origfd_) { return l::movefile(policy_,basepaths_,fusepath_,origfd_); } @@ -145,7 +177,7 @@ namespace fs movefile_as_root(const Policy::Create &policy_, const Branches::CPtr &basepaths_, const string &fusepath_, - int *origfd_) + int origfd_) { const ugid::Set ugid(0,0); diff --git a/src/fs_movefile.hpp b/src/fs_movefile.hpp index 8df1e1c2..a389ae10 100644 --- a/src/fs_movefile.hpp +++ b/src/fs_movefile.hpp @@ -28,11 +28,11 @@ namespace fs movefile(const Policy::Create &policy, const Branches::CPtr &branches, const std::string &fusepath, - int *origfd); + int origfd); int movefile_as_root(const Policy::Create &policy, const Branches::CPtr &branches, const std::string &fusepath, - int *origfd); + int origfd); } diff --git a/src/fuse_write.cpp b/src/fuse_write.cpp index 303b6cba..2be75ce2 100644 --- a/src/fuse_write.cpp +++ b/src/fuse_write.cpp @@ -44,28 +44,10 @@ namespace l static int - write_regular(const int fd_, - const void *buf_, - const size_t count_, - const off_t offset_) - { - int rv; - - rv = fs::pwrite(fd_,buf_,count_,offset_); - if(rv == -1) - return -errno; - if(rv == 0) - return 0; - - return count_; - } - - static - int - write_direct_io(const int fd_, - const void *buf_, - const size_t count_, - const off_t offset_) + write(const int fd_, + const void *buf_, + const size_t count_, + const off_t offset_) { int rv; @@ -78,8 +60,7 @@ namespace l static int - move_and_write(WriteFunc func_, - const char *buf_, + move_and_write(const char *buf_, const size_t count_, const off_t offset_, FileInfo *fi_, @@ -94,17 +75,18 @@ namespace l rv = fs::movefile_as_root(cfg->moveonenospc.policy, cfg->branches, fi_->fusepath, - &fi_->fd); - if(rv == -1) + fi_->fd); + if(rv < 0) return err_; - return func_(fi_->fd,buf_,count_,offset_); + fi_->fd = rv; + + return l::write(fi_->fd,buf_,count_,offset_); } static int write(const fuse_file_info_t *ffi_, - WriteFunc func_, const char *buf_, const size_t count_, const off_t offset_) @@ -114,9 +96,9 @@ namespace l fi = reinterpret_cast(ffi_->fh); - rv = func_(fi->fd,buf_,count_,offset_); + rv = l::write(fi->fd,buf_,count_,offset_); if(l::out_of_space(-rv)) - rv = l::move_and_write(func_,buf_,count_,offset_,fi,rv); + rv = l::move_and_write(buf_,count_,offset_,fi,rv); return rv; } @@ -130,13 +112,7 @@ namespace FUSE size_t count_, off_t offset_) { - WriteFunc wf; - - wf = ((ffi_->direct_io) ? - l::write_direct_io : - l::write_regular); - - return l::write(ffi_,wf,buf_,count_,offset_); + return l::write(ffi_,buf_,count_,offset_); } int