Browse Source

Merge pull request #832 from trapexit/rework-errors

rework some function error handling
pull/833/head
trapexit 4 years ago
committed by GitHub
parent
commit
9c352ac555
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 59
      src/fuse_chmod.cpp
  2. 59
      src/fuse_chown.cpp
  3. 21
      src/fuse_link.cpp
  4. 21
      src/fuse_mkdir.cpp
  5. 21
      src/fuse_mknod.cpp
  6. 60
      src/fuse_removexattr.cpp
  7. 24
      src/fuse_rename.cpp
  8. 21
      src/fuse_rmdir.cpp
  9. 158
      src/fuse_setxattr.cpp
  10. 22
      src/fuse_symlink.cpp
  11. 61
      src/fuse_truncate.cpp
  12. 23
      src/fuse_unlink.cpp
  13. 59
      src/fuse_utimens.cpp
  14. 42
      src/policy_rv.hpp

59
src/fuse_chmod.cpp

@ -18,7 +18,7 @@
#include "errno.hpp" #include "errno.hpp"
#include "fs_lchmod.hpp" #include "fs_lchmod.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "rv.hpp"
#include "policy_rv.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include "fuse.h" #include "fuse.h"
@ -31,57 +31,87 @@
using std::string; using std::string;
using std::vector; using std::vector;
namespace l namespace l
{ {
static static
int int
get_error(const PolicyRV &prv_,
const string &basepath_)
{
for(int i = 0, ei = prv_.success.size(); i < ei; i++)
{
if(prv_.success[i].basepath == basepath_)
return prv_.success[i].rv;
}
for(int i = 0, ei = prv_.error.size(); i < ei; i++)
{
if(prv_.error[i].basepath == basepath_)
return prv_.error[i].rv;
}
return 0;
}
static
void
chmod_loop_core(const string &basepath_, chmod_loop_core(const string &basepath_,
const char *fusepath_, const char *fusepath_,
const mode_t mode_, const mode_t mode_,
const int error_)
PolicyRV *prv_)
{ {
int rv;
string fullpath; string fullpath;
fullpath = fs::path::make(basepath_,fusepath_); fullpath = fs::path::make(basepath_,fusepath_);
rv = fs::lchmod(fullpath,mode_);
errno = 0;
fs::lchmod(fullpath,mode_);
return error::calc(rv,error_,errno);
prv_->insert(errno,basepath_);
} }
static static
int
void
chmod_loop(const vector<string> &basepaths_, chmod_loop(const vector<string> &basepaths_,
const char *fusepath_, const char *fusepath_,
const mode_t mode_)
const mode_t mode_,
PolicyRV *prv_)
{ {
int error;
error = -1;
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{ {
error = l::chmod_loop_core(basepaths_[i],fusepath_,mode_,error);
l::chmod_loop_core(basepaths_[i],fusepath_,mode_,prv_);
} }
return -error;
} }
static static
int int
chmod(Policy::Func::Action actionFunc_, chmod(Policy::Func::Action actionFunc_,
Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const mode_t mode_) const mode_t mode_)
{ {
int rv; int rv;
PolicyRV prv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,&basepaths); rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
return l::chmod_loop(basepaths,fusepath_,mode_);
l::chmod_loop(basepaths,fusepath_,mode_,&prv);
if(prv.error.empty())
return 0;
if(prv.success.empty())
return prv.error[0].rv;
basepaths.clear();
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
return l::get_error(prv,basepaths[0]);
} }
} }
@ -96,6 +126,7 @@ namespace FUSE
const ugid::Set ugid(fc->uid,fc->gid); const ugid::Set ugid(fc->uid,fc->gid);
return l::chmod(config.func.chmod.policy, return l::chmod(config.func.chmod.policy,
config.func.getattr.policy,
config.branches, config.branches,
fusepath_, fusepath_,
mode_); mode_);

59
src/fuse_chown.cpp

@ -18,7 +18,7 @@
#include "errno.hpp" #include "errno.hpp"
#include "fs_lchown.hpp" #include "fs_lchown.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "rv.hpp"
#include "policy_rv.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include <fuse.h> #include <fuse.h>
@ -29,60 +29,90 @@
using std::string; using std::string;
using std::vector; using std::vector;
namespace l namespace l
{ {
static static
int int
get_error(const PolicyRV &prv_,
const string &basepath_)
{
for(int i = 0, ei = prv_.success.size(); i < ei; i++)
{
if(prv_.success[i].basepath == basepath_)
return prv_.success[i].rv;
}
for(int i = 0, ei = prv_.error.size(); i < ei; i++)
{
if(prv_.error[i].basepath == basepath_)
return prv_.error[i].rv;
}
return 0;
}
static
void
chown_loop_core(const string &basepath_, chown_loop_core(const string &basepath_,
const char *fusepath_, const char *fusepath_,
const uid_t uid_, const uid_t uid_,
const gid_t gid_, const gid_t gid_,
const int error_)
PolicyRV *prv_)
{ {
int rv;
string fullpath; string fullpath;
fullpath = fs::path::make(basepath_,fusepath_); fullpath = fs::path::make(basepath_,fusepath_);
rv = fs::lchown(fullpath,uid_,gid_);
errno = 0;
fs::lchown(fullpath,uid_,gid_);
return error::calc(rv,error_,errno);
prv_->insert(errno,basepath_);
} }
static static
int
void
chown_loop(const vector<string> &basepaths_, chown_loop(const vector<string> &basepaths_,
const char *fusepath_, const char *fusepath_,
const uid_t uid_, const uid_t uid_,
const gid_t gid_)
const gid_t gid_,
PolicyRV *prv_)
{ {
int error;
error = -1;
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{ {
error = l::chown_loop_core(basepaths_[i],fusepath_,uid_,gid_,error);
l::chown_loop_core(basepaths_[i],fusepath_,uid_,gid_,prv_);
} }
return -error;
} }
static static
int int
chown(Policy::Func::Action actionFunc_, chown(Policy::Func::Action actionFunc_,
Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uid_t uid_, const uid_t uid_,
const gid_t gid_) const gid_t gid_)
{ {
int rv; int rv;
PolicyRV prv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,&basepaths); rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
return l::chown_loop(basepaths,fusepath_,uid_,gid_);
l::chown_loop(basepaths,fusepath_,uid_,gid_,&prv);
if(prv.error.empty())
return 0;
if(prv.success.empty())
return prv.error[0].rv;
basepaths.clear();
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
return l::get_error(prv,basepaths[0]);
} }
} }
@ -98,6 +128,7 @@ namespace FUSE
const ugid::Set ugid(fc->uid,fc->gid); const ugid::Set ugid(fc->uid,fc->gid);
return l::chown(config.func.chown.policy, return l::chown(config.func.chown.policy,
config.func.getattr.policy,
config.branches, config.branches,
fusepath_, fusepath_,
uid_, uid_,

21
src/fuse_link.cpp

@ -19,7 +19,6 @@
#include "fs_clonepath.hpp" #include "fs_clonepath.hpp"
#include "fs_link.hpp" #include "fs_link.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "rv.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include <fuse.h> #include <fuse.h>
@ -30,6 +29,26 @@
using std::string; using std::string;
using std::vector; using std::vector;
namespace error
{
static
inline
int
calc(const int rv_,
const int prev_,
const int cur_)
{
if(rv_ == -1)
{
if(prev_ == 0)
return 0;
return cur_;
}
return 0;
}
}
namespace l namespace l
{ {
static static

21
src/fuse_mkdir.cpp

@ -20,7 +20,6 @@
#include "fs_clonepath.hpp" #include "fs_clonepath.hpp"
#include "fs_mkdir.hpp" #include "fs_mkdir.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "rv.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include <fuse.h> #include <fuse.h>
@ -31,6 +30,26 @@
using std::string; using std::string;
using std::vector; using std::vector;
namespace error
{
static
inline
int
calc(const int rv_,
const int prev_,
const int cur_)
{
if(rv_ == -1)
{
if(prev_ == 0)
return 0;
return cur_;
}
return 0;
}
}
namespace l namespace l
{ {
static static

21
src/fuse_mknod.cpp

@ -20,7 +20,6 @@
#include "fs_mknod.hpp" #include "fs_mknod.hpp"
#include "fs_clonepath.hpp" #include "fs_clonepath.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "rv.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include <fuse.h> #include <fuse.h>
@ -31,6 +30,26 @@
using std::string; using std::string;
using std::vector; using std::vector;
namespace error
{
static
inline
int
calc(const int rv_,
const int prev_,
const int cur_)
{
if(rv_ == -1)
{
if(prev_ == 0)
return 0;
return cur_;
}
return 0;
}
}
namespace l namespace l
{ {
static static

60
src/fuse_removexattr.cpp

@ -18,7 +18,7 @@
#include "errno.hpp" #include "errno.hpp"
#include "fs_lremovexattr.hpp" #include "fs_lremovexattr.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "rv.hpp"
#include "policy_rv.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include <fuse.h> #include <fuse.h>
@ -29,58 +29,87 @@
using std::string; using std::string;
using std::vector; using std::vector;
namespace l namespace l
{ {
static static
int int
get_error(const PolicyRV &prv_,
const string &basepath_)
{
for(int i = 0, ei = prv_.success.size(); i < ei; i++)
{
if(prv_.success[i].basepath == basepath_)
return prv_.success[i].rv;
}
for(int i = 0, ei = prv_.error.size(); i < ei; i++)
{
if(prv_.error[i].basepath == basepath_)
return prv_.error[i].rv;
}
return 0;
}
static
void
removexattr_loop_core(const string &basepath_, removexattr_loop_core(const string &basepath_,
const char *fusepath_, const char *fusepath_,
const char *attrname_, const char *attrname_,
const int error_)
PolicyRV *prv_)
{ {
int rv;
string fullpath; string fullpath;
fullpath = fs::path::make(basepath_,fusepath_); fullpath = fs::path::make(basepath_,fusepath_);
rv = fs::lremovexattr(fullpath,attrname_);
errno = 0;
fs::lremovexattr(fullpath,attrname_);
return error::calc(rv,error_,errno);
prv_->insert(errno,basepath_);
} }
static static
int
void
removexattr_loop(const vector<string> &basepaths_, removexattr_loop(const vector<string> &basepaths_,
const char *fusepath_, const char *fusepath_,
const char *attrname_)
const char *attrname_,
PolicyRV *prv_)
{ {
int error;
error = -1;
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{ {
error = l::removexattr_loop_core(basepaths_[i],fusepath_,attrname_,error);
l::removexattr_loop_core(basepaths_[i],fusepath_,attrname_,prv_);
} }
return -error;
} }
static static
int int
removexattr(Policy::Func::Action actionFunc_, removexattr(Policy::Func::Action actionFunc_,
Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const char *attrname_) const char *attrname_)
{ {
int rv; int rv;
PolicyRV prv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,&basepaths); rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
return l::removexattr_loop(basepaths,fusepath_,attrname_);
l::removexattr_loop(basepaths,fusepath_,attrname_,&prv);
if(prv.error.empty())
return 0;
if(prv.success.empty())
return prv.error[0].rv;
basepaths.clear();
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
return l::get_error(prv,basepaths[0]);
} }
} }
@ -101,6 +130,7 @@ namespace FUSE
const ugid::Set ugid(fc->uid,fc->gid); const ugid::Set ugid(fc->uid,fc->gid);
return l::removexattr(config.func.removexattr.policy, return l::removexattr(config.func.removexattr.policy,
config.func.getxattr.policy,
config.branches, config.branches,
fusepath_, fusepath_,
attrname_); attrname_);

24
src/fuse_rename.cpp

@ -20,17 +20,35 @@
#include "fs_path.hpp" #include "fs_path.hpp"
#include "fs_remove.hpp" #include "fs_remove.hpp"
#include "fs_rename.hpp" #include "fs_rename.hpp"
#include "rv.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include <algorithm> #include <algorithm>
#include <set>
#include <string> #include <string>
#include <vector> #include <vector>
using std::string; using std::string;
using std::vector; using std::vector;
using std::set;
namespace error
{
static
inline
int
calc(const int rv_,
const int prev_,
const int cur_)
{
if(rv_ == -1)
{
if(prev_ == 0)
return 0;
return cur_;
}
return 0;
}
}
static static
bool bool

21
src/fuse_rmdir.cpp

@ -18,7 +18,6 @@
#include "errno.hpp" #include "errno.hpp"
#include "fs_rmdir.hpp" #include "fs_rmdir.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "rv.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include <fuse.h> #include <fuse.h>
@ -30,6 +29,23 @@
using std::string; using std::string;
using std::vector; using std::vector;
namespace error
{
static
int
calc(const int rv_,
const int prev_,
const int cur_)
{
if(prev_ != 0)
return prev_;
if(rv_ == -1)
return cur_;
return 0;
}
}
namespace l namespace l
{ {
static static
@ -48,7 +64,6 @@ namespace l
return error::calc(rv,error_,errno); return error::calc(rv,error_,errno);
} }
static static
int int
rmdir_loop(const vector<string> &basepaths_, rmdir_loop(const vector<string> &basepaths_,
@ -56,7 +71,7 @@ namespace l
{ {
int error; int error;
error = -1;
error = 0;
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{ {
error = l::rmdir_loop_core(basepaths_[i],fusepath_,error); error = l::rmdir_loop_core(basepaths_[i],fusepath_,error);

158
src/fuse_setxattr.cpp

@ -21,13 +21,12 @@
#include "fs_path.hpp" #include "fs_path.hpp"
#include "fs_statvfs_cache.hpp" #include "fs_statvfs_cache.hpp"
#include "num.hpp" #include "num.hpp"
#include "rv.hpp"
#include "policy_rv.hpp"
#include "str.hpp" #include "str.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include <fuse.h> #include <fuse.h>
#include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
@ -38,8 +37,29 @@ static const char SECURITY_CAPABILITY[] = "security.capability";
using std::string; using std::string;
using std::vector; using std::vector;
namespace l namespace l
{ {
static
int
get_error(const PolicyRV &prv_,
const string &basepath_)
{
for(int i = 0, ei = prv_.success.size(); i < ei; i++)
{
if(prv_.success[i].basepath == basepath_)
return prv_.success[i].rv;
}
for(int i = 0, ei = prv_.error.size(); i < ei; i++)
{
if(prv_.error[i].basepath == basepath_)
return prv_.error[i].rv;
}
return 0;
}
static static
bool bool
is_attrname_security_capability(const char *attrname_) is_attrname_security_capability(const char *attrname_)
@ -49,117 +69,126 @@ namespace l
static static
int int
setxattr_controlfile(Config &config,
const string &attrname,
const string &attrval,
const int flags)
setxattr_controlfile(Config &config_,
const string &attrname_,
const string &attrval_,
const int flags_)
{ {
int rv; int rv;
string key; string key;
if(!str::startswith(attrname,"user.mergerfs."))
if(!str::startswith(attrname_,"user.mergerfs."))
return -ENOATTR; return -ENOATTR;
key = &attrname[14];
key = &attrname_[14];
if(config.has_key(key) == false)
if(config_.has_key(key) == false)
return -ENOATTR; return -ENOATTR;
if((flags & XATTR_CREATE) == XATTR_CREATE)
if((flags_ & XATTR_CREATE) == XATTR_CREATE)
return -EEXIST; return -EEXIST;
rv = config.set(key,attrval);
rv = config_.set(key,attrval_);
if(rv < 0) if(rv < 0)
return rv; return rv;
config.open_cache.clear();
fs::statvfs_cache_timeout(config.cache_statfs);
config_.open_cache.clear();
fs::statvfs_cache_timeout(config_.cache_statfs);
return rv; return rv;
} }
static static
int
setxattr_loop_core(const string &basepath,
const char *fusepath,
const char *attrname,
const char *attrval,
const size_t attrvalsize,
const int flags,
const int error)
void
setxattr_loop_core(const string &basepath_,
const char *fusepath_,
const char *attrname_,
const char *attrval_,
const size_t attrvalsize_,
const int flags_,
PolicyRV *prv_)
{ {
int rv;
string fullpath; string fullpath;
fullpath = fs::path::make(basepath,fusepath);
fullpath = fs::path::make(basepath_,fusepath_);
rv = fs::lsetxattr(fullpath,attrname,attrval,attrvalsize,flags);
errno = 0;
fs::lsetxattr(fullpath,attrname_,attrval_,attrvalsize_,flags_);
return error::calc(rv,error,errno);
prv_->insert(errno,basepath_);
} }
static static
int
setxattr_loop(const vector<string> &basepaths,
const char *fusepath,
const char *attrname,
const char *attrval,
const size_t attrvalsize,
const int flags)
void
setxattr_loop(const vector<string> &basepaths_,
const char *fusepath_,
const char *attrname_,
const char *attrval_,
const size_t attrvalsize_,
const int flags_,
PolicyRV *prv_)
{ {
int error;
error = -1;
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{ {
error = l::setxattr_loop_core(basepaths[i],fusepath,
attrname,attrval,attrvalsize,flags,
error);
l::setxattr_loop_core(basepaths_[i],fusepath_,
attrname_,attrval_,attrvalsize_,
flags_,prv_);
} }
return -error;
} }
static static
int int
setxattr(Policy::Func::Action actionFunc,
setxattr(Policy::Func::Action actionFunc_,
Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const char *fusepath,
const char *attrname,
const char *attrval,
const size_t attrvalsize,
const int flags)
const char *fusepath_,
const char *attrname_,
const char *attrval_,
const size_t attrvalsize_,
const int flags_)
{ {
int rv; int rv;
PolicyRV prv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc(branches_,fusepath,&basepaths);
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
l::setxattr_loop(basepaths,fusepath_,attrname_,attrval_,attrvalsize_,flags_,&prv);
if(prv.error.empty())
return 0;
if(prv.success.empty())
return prv.error[0].rv;
basepaths.clear();
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
return l::setxattr_loop(basepaths,fusepath,attrname,attrval,attrvalsize,flags);
return l::get_error(prv,basepaths[0]);
} }
} }
namespace FUSE namespace FUSE
{ {
int int
setxattr(const char *fusepath,
const char *attrname,
const char *attrval,
size_t attrvalsize,
int flags)
setxattr(const char *fusepath_,
const char *attrname_,
const char *attrval_,
size_t attrvalsize_,
int flags_)
{ {
Config &config = Config::rw(); Config &config = Config::rw();
if(fusepath == config.controlfile)
if(fusepath_ == config.controlfile)
return l::setxattr_controlfile(config, return l::setxattr_controlfile(config,
attrname,
string(attrval,attrvalsize),
flags);
attrname_,
string(attrval_,attrvalsize_),
flags_);
if((config.security_capability == false) && if((config.security_capability == false) &&
l::is_attrname_security_capability(attrname))
l::is_attrname_security_capability(attrname_))
return -ENOATTR; return -ENOATTR;
if(config.xattr.to_int()) if(config.xattr.to_int())
@ -169,11 +198,12 @@ namespace FUSE
const ugid::Set ugid(fc->uid,fc->gid); const ugid::Set ugid(fc->uid,fc->gid);
return l::setxattr(config.func.setxattr.policy, return l::setxattr(config.func.setxattr.policy,
config.func.getxattr.policy,
config.branches, config.branches,
fusepath,
attrname,
attrval,
attrvalsize,
flags);
fusepath_,
attrname_,
attrval_,
attrvalsize_,
flags_);
} }
} }

22
src/fuse_symlink.cpp

@ -19,7 +19,6 @@
#include "fs_symlink.hpp" #include "fs_symlink.hpp"
#include "fs_clonepath.hpp" #include "fs_clonepath.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "rv.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include <fuse.h> #include <fuse.h>
@ -32,6 +31,27 @@
using std::string; using std::string;
using std::vector; using std::vector;
namespace error
{
static
inline
int
calc(const int rv_,
const int prev_,
const int cur_)
{
if(rv_ == -1)
{
if(prev_ == 0)
return 0;
return cur_;
}
return 0;
}
}
namespace l namespace l
{ {
static static

61
src/fuse_truncate.cpp

@ -16,9 +16,9 @@
#include "config.hpp" #include "config.hpp"
#include "errno.hpp" #include "errno.hpp"
#include "fs_truncate.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "rv.hpp"
#include "fs_truncate.hpp"
#include "policy_rv.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include <fuse.h> #include <fuse.h>
@ -32,57 +32,87 @@
using std::string; using std::string;
using std::vector; using std::vector;
namespace l namespace l
{ {
static static
int int
get_error(const PolicyRV &prv_,
const string &basepath_)
{
for(int i = 0, ei = prv_.success.size(); i < ei; i++)
{
if(prv_.success[i].basepath == basepath_)
return prv_.success[i].rv;
}
for(int i = 0, ei = prv_.error.size(); i < ei; i++)
{
if(prv_.error[i].basepath == basepath_)
return prv_.error[i].rv;
}
return 0;
}
static
void
truncate_loop_core(const string &basepath_, truncate_loop_core(const string &basepath_,
const char *fusepath_, const char *fusepath_,
const off_t size_, const off_t size_,
const int error_)
PolicyRV *prv_)
{ {
int rv;
string fullpath; string fullpath;
fullpath = fs::path::make(basepath_,fusepath_); fullpath = fs::path::make(basepath_,fusepath_);
rv = fs::truncate(fullpath,size_);
errno = 0;
fs::truncate(fullpath,size_);
return error::calc(rv,error_,errno);
prv_->insert(errno,basepath_);
} }
static static
int
void
truncate_loop(const vector<string> &basepaths_, truncate_loop(const vector<string> &basepaths_,
const char *fusepath_, const char *fusepath_,
const off_t size_)
const off_t size_,
PolicyRV *prv_)
{ {
int error;
error = -1;
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{ {
error = l::truncate_loop_core(basepaths_[i],fusepath_,size_,error);
l::truncate_loop_core(basepaths_[i],fusepath_,size_,prv_);
} }
return -error;
} }
static static
int int
truncate(Policy::Func::Action actionFunc_, truncate(Policy::Func::Action actionFunc_,
Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const off_t size_) const off_t size_)
{ {
int rv; int rv;
PolicyRV prv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,&basepaths); rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
return l::truncate_loop(basepaths,fusepath_,size_);
l::truncate_loop(basepaths,fusepath_,size_,&prv);
if(prv.error.empty())
return 0;
if(prv.success.empty())
return prv.error[0].rv;
basepaths.clear();
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
return l::get_error(prv,basepaths[0]);
} }
} }
@ -97,6 +127,7 @@ namespace FUSE
const ugid::Set ugid(fc->uid,fc->gid); const ugid::Set ugid(fc->uid,fc->gid);
return l::truncate(config.func.truncate.policy, return l::truncate(config.func.truncate.policy,
config.func.getattr.policy,
config.branches, config.branches,
fusepath_, fusepath_,
size_); size_);

23
src/fuse_unlink.cpp

@ -16,9 +16,8 @@
#include "config.hpp" #include "config.hpp"
#include "errno.hpp" #include "errno.hpp"
#include "fs_unlink.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "rv.hpp"
#include "fs_unlink.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include <fuse.h> #include <fuse.h>
@ -31,6 +30,24 @@
using std::string; using std::string;
using std::vector; using std::vector;
namespace error
{
static
inline
int
calc(const int rv_,
const int prev_,
const int cur_)
{
if(prev_ != 0)
return prev_;
if(rv_ == -1)
return cur_;
return 0;
}
}
namespace l namespace l
{ {
static static
@ -56,7 +73,7 @@ namespace l
{ {
int error; int error;
error = -1;
error = 0;
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{ {
error = l::unlink_loop_core(basepaths_[i],fusepath_,error); error = l::unlink_loop_core(basepaths_[i],fusepath_,error);

59
src/fuse_utimens.cpp

@ -18,7 +18,7 @@
#include "errno.hpp" #include "errno.hpp"
#include "fs_lutimens.hpp" #include "fs_lutimens.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "rv.hpp"
#include "policy_rv.hpp"
#include "ugid.hpp" #include "ugid.hpp"
#include <fuse.h> #include <fuse.h>
@ -31,57 +31,87 @@
using std::string; using std::string;
using std::vector; using std::vector;
namespace l namespace l
{ {
static static
int int
get_error(const PolicyRV &prv_,
const string &basepath_)
{
for(int i = 0, ei = prv_.success.size(); i < ei; i++)
{
if(prv_.success[i].basepath == basepath_)
return prv_.success[i].rv;
}
for(int i = 0, ei = prv_.error.size(); i < ei; i++)
{
if(prv_.error[i].basepath == basepath_)
return prv_.error[i].rv;
}
return 0;
}
static
void
utimens_loop_core(const string &basepath_, utimens_loop_core(const string &basepath_,
const char *fusepath_, const char *fusepath_,
const timespec ts_[2], const timespec ts_[2],
const int error_)
PolicyRV *prv_)
{ {
int rv;
string fullpath; string fullpath;
fullpath = fs::path::make(basepath_,fusepath_); fullpath = fs::path::make(basepath_,fusepath_);
rv = fs::lutimens(fullpath,ts_);
errno = 0;
fs::lutimens(fullpath,ts_);
return error::calc(rv,error_,errno);
prv_->insert(errno,basepath_);
} }
static static
int
void
utimens_loop(const vector<string> &basepaths_, utimens_loop(const vector<string> &basepaths_,
const char *fusepath_, const char *fusepath_,
const timespec ts_[2])
const timespec ts_[2],
PolicyRV *prv_)
{ {
int error;
error = -1;
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{ {
error = l::utimens_loop_core(basepaths_[i],fusepath_,ts_,error);
l::utimens_loop_core(basepaths_[i],fusepath_,ts_,prv_);
} }
return -error;
} }
static static
int int
utimens(Policy::Func::Action actionFunc_, utimens(Policy::Func::Action actionFunc_,
Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const timespec ts_[2]) const timespec ts_[2])
{ {
int rv; int rv;
PolicyRV prv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,&basepaths); rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
return l::utimens_loop(basepaths,fusepath_,ts_);
l::utimens_loop(basepaths,fusepath_,ts_,&prv);
if(prv.error.empty())
return 0;
if(prv.success.empty())
return prv.error[0].rv;
basepaths.clear();
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
return l::get_error(prv,basepaths[0]);
} }
} }
@ -96,6 +126,7 @@ namespace FUSE
const ugid::Set ugid(fc->uid,fc->gid); const ugid::Set ugid(fc->uid,fc->gid);
return l::utimens(config.func.utimens.policy, return l::utimens(config.func.utimens.policy,
config.func.getattr.policy,
config.branches, config.branches,
fusepath_, fusepath_,
ts_); ts_);

42
src/rv.hpp → src/policy_rv.hpp

@ -1,5 +1,7 @@
/* /*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -16,22 +18,34 @@
#pragma once #pragma once
namespace error
#include <string>
#include <vector>
struct PolicyRV
{ {
static
inline
int
calc(const int rv_,
const int prev_,
const int cur_)
struct RV
{ {
if(rv_ == -1)
RV(const int rv_,
const std::string &basepath_)
: rv(rv_),
basepath(basepath_)
{ {
if(prev_ == 0)
return 0;
return cur_;
} }
return 0;
int rv;
std::string basepath;
};
std::vector<RV> success;
std::vector<RV> error;
void
insert(const int err_,
const std::string &basepath_)
{
if(err_ == 0)
success.push_back(RV(err_,basepath_));
else
error.push_back(RV(-err_,basepath_));
} }
}
};
Loading…
Cancel
Save