Browse Source

Fix moveonenospc when file opened with append mode

pull/1203/head
Antonio SJ Musumeci 2 years ago
parent
commit
82430e1079
  1. 8
      src/fs_copydata_readwrite.cpp
  2. 2
      src/fs_mktemp.cpp
  3. 150
      src/fs_movefile.cpp
  4. 4
      src/fs_movefile.hpp
  5. 44
      src/fuse_write.cpp

8
src/fs_copydata_readwrite.cpp

@ -57,8 +57,7 @@ namespace l
int int
copydata_readwrite(const int src_fd_, copydata_readwrite(const int src_fd_,
const int dst_fd_, const int dst_fd_,
const size_t count_,
const size_t blocksize_)
const size_t count_)
{ {
ssize_t nr; ssize_t nr;
ssize_t nw; ssize_t nw;
@ -66,7 +65,7 @@ namespace l
size_t totalwritten; size_t totalwritten;
vector<char> buf; vector<char> buf;
bufsize = (blocksize_ * 16);
bufsize = (128 * 1024);
buf.resize(bufsize); buf.resize(bufsize);
fs::lseek(src_fd_,0,SEEK_SET); fs::lseek(src_fd_,0,SEEK_SET);
@ -108,7 +107,6 @@ namespace fs
return l::copydata_readwrite(src_fd_, return l::copydata_readwrite(src_fd_,
dst_fd_, dst_fd_,
st.st_size,
st.st_blksize);
st.st_size);
} }
} }

2
src/fs_mktemp.cpp

@ -59,7 +59,7 @@ namespace fs
fd = -1; fd = -1;
count = MAX_ATTEMPTS; count = MAX_ATTEMPTS;
flags = (flags_ | O_EXCL | O_CREAT);
flags = (flags_ | O_EXCL | O_CREAT | O_TRUNC);
while(count-- > 0) while(count-- > 0)
{ {
tmppath = generate_tmp_path(*base_); tmppath = generate_tmp_path(*base_);

150
src/fs_movefile.cpp

@ -44,6 +44,21 @@ using std::string;
using std::vector; 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 namespace l
{ {
static static
@ -51,82 +66,99 @@ namespace l
movefile(const Policy::Create &createFunc_, movefile(const Policy::Create &createFunc_,
const Branches::CPtr &branches_, const Branches::CPtr &branches_,
const string &fusepath_, const string &fusepath_,
int *origfd_)
int origfd_)
{ {
int rv; 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 fusedir;
string fdin_path;
string fdout_temp;
vector<string> fdout_path;
fdin = *origfd_;
string srcfd_branch;
string srcfd_filepath;
string dstfd_filepath;
string dstfd_tmp_filepath;
vector<string> 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) if(rv == -1)
return -1;
return -errno;
rv = createFunc_(branches_,fusepath_,&fdout_path);
rv = createFunc_(branches_,fusepath_,&dstfd_branch);
if(rv == -1) 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_); 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) 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;
}
fs::path::append(fdout_path[0],fusepath_);
fdout_temp = fdout_path[0];
fdout = fs::mktemp(&fdout_temp,fdin_flags);
if(fdout == -1)
return -1;
rv = fs::clonefile(srcfd,dstfd);
if(rv == -1)
{
fs::close(srcfd);
fs::close(dstfd);
fs::unlink(dstfd_tmp_filepath);
return -ENOSPC;
}
rv = fs::clonefile(fdin,fdout);
rv = fs::rename(dstfd_tmp_filepath,dstfd_filepath);
if(rv == -1) if(rv == -1)
goto cleanup;
{
fs::close(srcfd);
fs::close(dstfd);
fs::unlink(dstfd_tmp_filepath);
return -ENOSPC;
}
rv = fs::rename(fdout_temp,fdout_path[0]);
fs::close(srcfd);
fs::close(dstfd);
dstfd_flags = ::cleanup_flags(origfd_flags);
rv = fs::open(dstfd_filepath,dstfd_flags);
if(rv == -1) 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;
{
fs::unlink(dstfd_tmp_filepath);
return -ENOSPC;
}
fs::unlink(srcfd_filepath);
fs::close(origfd_);
return rv;
} }
} }
@ -136,7 +168,7 @@ namespace fs
movefile(const Policy::Create &policy_, movefile(const Policy::Create &policy_,
const Branches::CPtr &basepaths_, const Branches::CPtr &basepaths_,
const string &fusepath_, const string &fusepath_,
int *origfd_)
int origfd_)
{ {
return l::movefile(policy_,basepaths_,fusepath_,origfd_); return l::movefile(policy_,basepaths_,fusepath_,origfd_);
} }
@ -145,7 +177,7 @@ namespace fs
movefile_as_root(const Policy::Create &policy_, movefile_as_root(const Policy::Create &policy_,
const Branches::CPtr &basepaths_, const Branches::CPtr &basepaths_,
const string &fusepath_, const string &fusepath_,
int *origfd_)
int origfd_)
{ {
const ugid::Set ugid(0,0); const ugid::Set ugid(0,0);

4
src/fs_movefile.hpp

@ -28,11 +28,11 @@ namespace fs
movefile(const Policy::Create &policy, movefile(const Policy::Create &policy,
const Branches::CPtr &branches, const Branches::CPtr &branches,
const std::string &fusepath, const std::string &fusepath,
int *origfd);
int origfd);
int int
movefile_as_root(const Policy::Create &policy, movefile_as_root(const Policy::Create &policy,
const Branches::CPtr &branches, const Branches::CPtr &branches,
const std::string &fusepath, const std::string &fusepath,
int *origfd);
int origfd);
} }

44
src/fuse_write.cpp

@ -44,25 +44,7 @@ namespace l
static static
int 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_,
write(const int fd_,
const void *buf_, const void *buf_,
const size_t count_, const size_t count_,
const off_t offset_) const off_t offset_)
@ -78,8 +60,7 @@ namespace l
static static
int int
move_and_write(WriteFunc func_,
const char *buf_,
move_and_write(const char *buf_,
const size_t count_, const size_t count_,
const off_t offset_, const off_t offset_,
FileInfo *fi_, FileInfo *fi_,
@ -94,17 +75,18 @@ namespace l
rv = fs::movefile_as_root(cfg->moveonenospc.policy, rv = fs::movefile_as_root(cfg->moveonenospc.policy,
cfg->branches, cfg->branches,
fi_->fusepath, fi_->fusepath,
&fi_->fd);
if(rv == -1)
fi_->fd);
if(rv < 0)
return err_; return err_;
return func_(fi_->fd,buf_,count_,offset_);
fi_->fd = rv;
return l::write(fi_->fd,buf_,count_,offset_);
} }
static static
int int
write(const fuse_file_info_t *ffi_, write(const fuse_file_info_t *ffi_,
WriteFunc func_,
const char *buf_, const char *buf_,
const size_t count_, const size_t count_,
const off_t offset_) const off_t offset_)
@ -114,9 +96,9 @@ namespace l
fi = reinterpret_cast<FileInfo*>(ffi_->fh); fi = reinterpret_cast<FileInfo*>(ffi_->fh);
rv = func_(fi->fd,buf_,count_,offset_);
rv = l::write(fi->fd,buf_,count_,offset_);
if(l::out_of_space(-rv)) 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; return rv;
} }
@ -130,13 +112,7 @@ namespace FUSE
size_t count_, size_t count_,
off_t offset_) 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 int

Loading…
Cancel
Save